kubeadm 简介

工作原理

  • kubernetes 由于部署复杂,社区提出了一个想法:为什么不用容器部署 kubernetes 呢?只要给每个 Kubernetes 组建做一个容器镜像,然后使用 docker 运行即可。
  • 但是由于 kubelet 除了和容器打交道,在配置容器网络、管理容器 Volume 时,都需要直接操作宿主机,kubelet 如果本身就在一个容器里运行,那么直接操作宿主机就变得非常麻烦
  • 因此 kubeadm 选择了一种妥协方案:直接在宿主机上运行 kubelet,然后使用容器部署其他 Kubernetes 组件

Kubeadm init(初始化 Master) 工作流程

  • 进行 Preflight Checks,校验主机是否可以部署 kubernetes
  • 申请证书,证书默认都放在 /etc/kubernetes/pki 目录下
  • 为其他组件生成访问 kube-apiserver 所需的配置文件(/etc/kubernetes/xxx.conf),这些文件里记录的是当前这个 Master 节点的服务器地址、监听端口、证书目录等
  • kubeadm 为 Master 组件生成 Pod 配置文件(kube-apiserver、kube-controller-manager、kube-scheduler 都会通过 Pod 的方式部署)
    • Master 组件的 YAML 文件会被生成在 /etc/kubernetes/manifests 路径下
    • 这几个容器通过 Static Pod 的方式启动,当一台机的 kubelet 启动时,他会自动检查该目录,加载所有 Pod YAML 文件并在这台机器上启动它们
  • 生成一个 etcd 的 Pod YAML 文件,也用来通过 Static Pod 的方式启动 etcd
  • 然后 kubeadm 会为集群生成一个 bootstrap token,之后只要持有这个 token,任何安装了 kubenet 和 kubeadm 的节点都可以通过 kubeadm join 加入这个集群
    • token 生成后,kubeadm 会将 ca.crt 等 Master 节点的重要信息,通过 ConfigMap 的方式保存在 etcd 中,供后续部署 Node 节点使用

kubeadm join(Node 加入 Master) 的工作流程

  • 由于 kubernetes 集群新增任何一个节点,都需要在 kube-apiserver 上注册,可是要跟 kube-apiserver 进行通信,这台机器就必须先获得相应的证书文件,可是为了能够一键安装,自然不能手动去 Master 节点上复制证书文件。
  • 因此 kubeadm 需要发起一次 “非安全模式” 的访问到 kube-apiserver,从而拿到保存在 ConfigMap 中的 cluster-info(他保存了 apiserver 的授权信息),因此 bootstrap token 扮演了安全验证的角色
  • 只要有了 cluster-info 中的 kube-apiserver 的地址、端口、证书,kubelet 就可以以 “安全模式” 连接到 apiserver 上,这样一个新的节点就部署完成了

部署

安装 kubeadm 和 docker

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 安装必要的一些系统工具
apt-get update && apt -y upgrade
apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# 安装 docker GPG 证书
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 写入 docker 软件源信息
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 写入 kubernetes GPG
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - 
# 写入 kubernetes 源
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
# 安装 docker kubeadm
apt-get update
apt-cache madison docker-ce
sudo apt-get -y install docker-ce=5:19.03.15~3-0~ubuntu-focal
apt-get install -y kubelet=1.20.4-00 kubeadm=1.20.4-00 kubectl=1.20.4-00
  • 配置镜像加速 和 cgoup
1
2
3
4
5
6
7
8
mkdir /etc/docker
vi /etc/docker/daemon.json
{
  "registry-mirrors": ["https://jhd12sgk.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker
  • 关闭 swap
1
2
3
4
5
6
7
# 关闭 swap 自动挂载
vim /etc/fstab
# 立刻摘除 swap
swapoff -a
# 调整 swap 使用的阈值
echo "vm.swappiness = 0" >> /etc/sysctl.conf
sysctl -p

kubeadm init

  • 配置 kubeadm 用的 YAML 文件
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
$ vi kubeadm.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
nodeRegistration:
  kubeletExtraArgs:
    cgroup-driver: "systemd"
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: "v1.20.4"
clusterName: "example-cluster"
controllerManager:
  extraArgs:
    horizontal-pod-autoscaler-use-rest-clients: "true"
    horizontal-pod-autoscaler-sync-period: "10s"
apiServer:
  extraArgs:
    runtime-config: "api/all=true"
    advertise-address: 192.168.1.200
imageRepository: "registry.cn-hangzhou.aliyuncs.com/google_containers"
  • 拉取镜像
1
kubeadm config images pull --config=kubeadm.yaml
  • 初始化
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
$ kubeadm init --config=kubeadm.yaml
Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

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

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.1.200:6443 --token krgn7i.tq1gvosqrba8srte \
    --discovery-token-ca-cert-hash sha256:f476eeb222f9a968bb43bb909beef58df198bfb204baedff7a8db7ce40aca387
  • 配置基本命令
1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

kubeadm join

  • 从节点依赖配置
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 安装必要的一些系统工具
apt-get update && apt -y upgrade
apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# 安装 docker GPG 证书
curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# 写入 docker 软件源信息
sudo add-apt-repository "deb [arch=amd64] https://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# 写入 kubernetes GPG
curl https://mirrors.aliyun.com/kubernetes/apt/doc/apt-key.gpg | sudo apt-key add - 
# 写入 kubernetes 源
cat <<EOF >/etc/apt/sources.list.d/kubernetes.list
deb https://mirrors.aliyun.com/kubernetes/apt/ kubernetes-xenial main
EOF
# 安装 docker kubeadm
apt-get update
apt-cache madison docker-ce
sudo apt-get -y install docker-ce=5:19.03.15~3-0~ubuntu-focal
apt-get install -y kubelet=1.20.4-00 kubeadm=1.20.4-00

# 关闭 swap
vim /etc/fstab
swapoff -a
echo "vm.swappiness = 0" >> /etc/sysctl.conf
sysctl -p

mkdir /etc/docker
vi /etc/docker/daemon.json
{
  "registry-mirrors": ["https://jhd12sgk.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
sudo systemctl daemon-reload
sudo systemctl restart docker
  • node 节点加入 集群
1
2
kubeadm join 192.168.1.200:6443 --token krgn7i.tq1gvosqrba8srte \
    --discovery-token-ca-cert-hash sha256:f476eeb222f9a968bb43bb909beef58df198bfb204baedff7a8db7ce40aca387
  • 相关命令
1
2
3
4
5
6
7
#节点加入命令格式如下:
kubeadm join --token <token> <control-plane-host>:<control-plane-port> --discovery-token-ca-cert-hash sha256:<hash>

#查询当前token
kubeadm token list
#查看 --discovery-token-ca-cert-hash的值
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

配置容器网络

1
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d '\n')"

测试

  • 查看 node 状态
1
2
3
4
5
$ kubectl get nodes
NAME         STATUS   ROLES                  AGE   VERSION
k8s-master   Ready    control-plane,master   24h   v1.20.4
k8s-node02   Ready    <none>                 23h   v1.20.4
k8s-node1    Ready    <none>                 23h   v1.20.4
  • 运行一个容器
    • k8s 不推荐使用 命令的方式直接运行容器,而是希望使用 YAML 文件的方式,把容器的定义、参数、配置统统记录在一个 YAML 文件中
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
$ vi nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

$ kubectl create -f nginx-deployment.yaml
$ kubectl get pods
NAME                                READY   STATUS              RESTARTS   AGE
nginx-deployment-5d59d67564-n4tth   0/1     ContainerCreating   0          31s
nginx-deployment-5d59d67564-nljwb   0/1     ContainerCreating   0          31s

部署 rook ceph

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
$ wget https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/common.yaml
$ wget https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/crds.yaml
$ wget https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/operator.yaml
$ wget https://raw.githubusercontent.com/rook/rook/master/cluster/examples/kubernetes/ceph/cluster.yaml

$ vi operator.yaml
  ROOK_CSI_CEPH_IMAGE: "quay.io/cephcsi/cephcsi:v3.4.0"
  ROOK_CSI_REGISTRAR_IMAGE: "registry.aliyuncs.com/it00021hot/csi-node-driver-registrar:v2.2.0"
  ROOK_CSI_RESIZER_IMAGE: "registry.aliyuncs.com/it00021hot/csi-resizer:v1.2.0"
  ROOK_CSI_PROVISIONER_IMAGE: "registry.aliyuncs.com/it00021hot/csi-provisioner:v2.2.2"
  ROOK_CSI_SNAPSHOTTER_IMAGE: "registry.aliyuncs.com/it00021hot/csi-snapshotter:v4.1.1"
  ROOK_CSI_ATTACHER_IMAGE: "registry.aliyuncs.com/it00021hot/csi-attacher:v3.2.1"

$ vi cluster.yaml
  storage: # cluster level storage configuration and selection
    useAllNodes: false
    useAllDevices: false
    deviceFilter: sdb
    nodes:
    - name: "k8s-node1"  #指定存储节点主机
      devices:
      - name: "sdb"    #指定磁盘为/dev/sdb
    - name: "k8s-node2"
      devices:
      - name: "sdb"
    
    dashboard:
      enabled: true
      # serve the dashboard under a subpath (useful when you are accessing the dashboard via a reverse proxy)
      # urlPrefix: /ceph-dashboard
      # serve the dashboard at the given port.
      # port: 8443
      # serve the dashboard using SSL
      ssl: false

$ kubectl apply -f common.yaml
$ kubectl apply -f crds.yaml
$ kubectl apply -f operator.yaml
$ kubectl apply -f cluster.yaml