0%

使用 Kubeadm 安装 Kubernetes

学习新技术提升自我价值,Kubernetes 是 Google 开源的容器集群管理系统,对于容器运行时、编排、常规服务都抽象设计出标准完整的 API。

简介

跟着官方文档学习使用 Kubeadm 安装 Kubernetes。由于中文文档和英文文档有差别,选择使用英文文档进行学习安装。

由于官方文档较复杂,跟着【K8S 笔记 - 使用 kubeadm 安装 k8s】学习了部分内容,做了部分修改。修改的原因是在搭建学习 kubernets 过程中了解到 kubernetes 已经在高版本移除了 dockershim 且,containerd 运行时是 docker 项目拆分出来的容器运行时,所以直接选择 containerd 作为容器运行时。

其他参考文档:

以下是本文档使用到的服务和对应的信息

序号 服务 版本 描述
1 containerd.io 1.6.4 容器运行时
2 runc 1.1.1 是一个命令行工具端,根据OCI(开放容器组织)的标准来创建和运行容器。
3 flannel 1.0.1 网络插件
5 Calico 1.0.1 网络插件
4 kubeadm 1.24.0 kubernetes 安装工具
5 kubectl 1.24.0 kubernetes 命令行工具
6 kubelet 1.24.0 一个在集群中每个节点(node)上运行的代理。
7 containerd 1.6.4 容器运行时

准备 linux 环境

  • 在 VMware Workstation 上安装 Centos 7.9 版本的linux。
    可参考【在 VMware 上安装最小化 Centos 7.9】

  • 系统初始化配置
    可参考【最小化 CentOS 7 初始环境配置】

  • 然后克隆两台服务器,当然此操作也可以在虚拟机完成所有基础环境安装完成后,再进行克隆。
    可参考【VMware Workstation 克隆镜像–快速搭建Centos 系统】
    为了方便识别,将主机名称修改,修改的信息参考下方的列表信息。

    1
    2
    3
    hostnamectl set-hostname k8s-master
    hostnamectl set-hostname k8s-slave-1
    hostnamectl set-hostname k8s-salve-2

    并将IP和hostname信息添加至 hosts

    1
    2
    3
    4
    5
    cat >> /etc/hosts << EOF
    128.196.66.10 k8s-master
    128.196.66.11 k8s-slave-1
    128.196.66.12 k8s-slave-2
    EOF
  • 将准备完成的虚拟机根据官方要求,将虚拟机硬件配置进行调整

    • CPU 修改为 2 核
    • 内存修改为 2GB
  • 关闭 firewalld
    由于是学习环境,直接关闭防火墙。生产环境建议开启系统防火墙保证安全性,根据官方文档检查所需端口,开启必要的端口。

    1
    2
    systemctl stop firewalld
    systemctl disable firewalld
  • 关闭交换分区
    为了保证 kubelet 正常工作,你 必须 禁用交换分区。

    在 Kubernetes 1.22 之前,节点不支持使用交换内存,并且默认情况下, 如果在节点上检测到交换内存配置,kubelet 将无法启动。 在 1.22 以后,可以 逐个节点地启用交换内存支持。但这还在 alpha 阶段。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 查看swap分区情况
    swapon
    free -h

    # 关闭所有 swap 分区
    # 临时关闭
    swapoff -a
    # 永久关闭
    vim /etc/fstab # 将 swap 行注释,保存退出。然后重启服务器。
    # set -i '/swap/s/^/#/g' /etc/fstab
  • 环境详情

    IP 服务器名称 安装服务
    128.196.66.10 k8s-master containerd.io
    kubeadm
    kubectl
    kubelet
    flannel
    128.196.66.11 k8s-slave-1 containerd.io
    kubeadm
    kubectl
    kubelet
    flannel
    128.196.66.12 k8s-slave-2 containerd.io
    kubeadm
    kubectl
    kubelet
    flannel

    环境准备完成后使用 Xshell (官方家庭版本),进行SSH连接。可使用另一个开源工具 WindTerm 连接,此客户端是由于办公时网络限制且不能安装软件, 通过此软件进行 SSH 连接。

    安装

    安装过程中,若没有指出仅在 slave 端安装,默认所有服务器上都需要安装对应的服务。本文使用的是 root 用户进行安装的,如果是其他用户安装需要 su

    安装容器运行时

    本文档安装的是 containerd 容器运行时,参考文档 【Getting started with containerd】。本文档使用的是最新版本 1.6.4。使用 yum 的安装方式进行安装。

    安装前准备

    • 转发 IPv4 并使 iptables 可以桥接流量

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      cat <<EOF | tee /etc/modules-load.d/k8s.conf
      overlay
      br_netfilter
      EOF

      sudo modprobe overlay
      sudo modprobe br_netfilter

      # sysctl params required by setup, params persist across reboots
      cat <<EOF | tee /etc/sysctl.d/k8s.conf
      net.bridge.bridge-nf-call-iptables = 1
      net.bridge.bridge-nf-call-ip6tables = 1
      net.ipv4.ip_forward = 1
      EOF

      # Apply sysctl params without reboot
      sudo sysctl --system
    • Cgroup 驱动
      本文档使用的是 Cgroup V1 版本,在运行中的 POD 修改 Cgroup 驱动是不明智的,因为重新修改后仍然可能会出现问题。

      kubernetes 仅支持相同版本的 cgroup 驱动,因此建议在搭建集群的时候就需要考虑使用 Cgroup V1 还是 V2。

      修改配置文件,设置为 SystemdCgroup = true,此操作会在安装配置中修改对应的内容。

    • 移除旧版本

      1
      yum remove -y containerd.io
    • 配置镜像,本文档通过官方脚本进行配置

      1
      2
      3
      4
      5
      6
      7
      8
      # 下载脚本
      curl -fsSL https://get.docker.com -o get-docker.sh
      # 设置镜像源为 阿里云
      DRY_RUN=1 sh get-docker.sh --mirror Aliyun # 执行后会有操作内容,根据提示的内容进行操作
      # 安装 yum-utils
      yum install -y -q yum-utils
      # 创建新的 yum repository
      yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    • 安装 containerd.io 并启动

      1
      2
      3
      4
      # 安装 containerd.io,由于此脚本会有docker相关的,仅复制安装了一个内容
      yum -y install containerd.io # 此包包含 runc
      # 启动并加入 systemd
      systemctl enable --now containerd
    • 生成配置文件,并将 Cgroup 开启

      1
      2
      3
      4
      5
      6
      7
      8
      # 生成默认的配置文件
      containerd config default > /etc/containerd/config.toml
      # 修改配置文件中的内容,将 SystemdCgroup 开启
      sed -i '/SystemdCgroup/s/SystemdCgroup =.*/SystemdCgroup = true/' /etc/containerd/config.toml
      # 修改配置文件中的内容,将 *sandbox_image* 源修改为 阿里云
      sed -i 's#k8s.gcr.io#registry.cn-hangzhou.aliyuncs.com/google_containers#' /etc/containerd/config.toml
      # 重启服务
      systemctl restart containerd

    安装 kubeadm kubelet kubectl

    • 安装
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      # 配置 阿里云 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=0
      EOF

      # 安装
      sudo yum install -y kubectl kubelet kubeadm
      # 服务器启动后自动启动该 kubelet
      systemctl enable kubelet

    初始化 kubeadm(master)

    • 初始化前准备

      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
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      # 创建配置文件,详细如下
      mkdir /data/k8s/ -p
      cat > /data/k8s/kubeadm.yaml << EOF
      apiVersion: kubeadm.k8s.io/v1beta3
      bootstrapTokens:
      - groups:
      - system:bootstrappers:kubeadm:default-node-token
      token: abcdef.0123456789abcdef
      ttl: 24h0m0s
      usages:
      - signing
      - authentication
      kind: InitConfiguration
      localAPIEndpoint:
      advertiseAddress: 128.196.66.10
      bindPort: 6443
      nodeRegistration:
      criSocket: unix:///run/containerd/containerd.sock
      imagePullPolicy: IfNotPresent
      name: k8s-master
      taints:
      - effect: NoSchedule
      key: node-role.kubernetes.io/master
      ---
      apiServer:
      timeoutForControlPlane: 4m0s
      apiVersion: kubeadm.k8s.io/v1beta3
      certificatesDir: /etc/kubernetes/pki
      clusterName: kubernetes
      controllerManager: {}
      dns: {}
      etcd:
      local:
      dataDir: /var/lib/etcd
      imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
      kind: ClusterConfiguration
      kubernetesVersion: v1.24.0
      networking:
      dnsDomain: cluster.local
      podSubnet: 10.244.0.0/16
      serviceSubnet: 10.96.0.0/12
      scheduler: {}
      EOF

      # 查看可用镜像
      kubeadm config images list --config /data/k8s/kubeadm.yaml
      # 下载镜像
      kubeadm config images pull --config /data/k8s/kubeadm.yaml

      # 初始化 master
      kubeadm init --config /data/k8s/kubeadm.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
      [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
      [addons] Applied essential addon: CoreDNS
      [addons] Applied essential addon: kube-proxy

      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 128.196.66.10:6443 --token abcdef.0123456789abcdef \
      --discovery-token-ca-cert-hash sha256:a917905179990bb84d948f6b0e3592dfeae3d4400a10b03de7f5760717328e10

      最后一行也显示了 slave 加入master 的详细命令。后续 slave 加入master 输入此内容即可。

    • 根据输出的内容操作

      1
      2
      3
      4
      5
      mkdir -p $HOME/.kube
      sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      sudo chown $(id -u):$(id -g) $HOME/.kube/config
      export KUBECONFIG=/etc/kubernetes/admin.conf >> ~/.bash_profile
      source ~/.bash_profile
    • 查看 node

      1
      2
      3
      4
      5
      # 由于还未安装网络组件,状态都为 NotReady
      # kubectl get node 同样可以
      kubectl get nodes
      # 使用以下命令也可以查看 node 详细信息
      kubectl describe node k8s-master | grep network

    slave 加入集群

    1
    2
    3
    # 根据kubeadm master 安装成功后提示的内容进行操作
    kubeadm join 128.196.66.10:6443 --token abcdef.0123456789abcdef \
    --discovery-token-ca-cert-hash sha256:a917905179990bb84d948f6b0e3592dfeae3d4400a10b03de7f5760717328e10

    master 查看集群

    1
    2
    3
    4
    # 查看 node 信息
    kubectl get node # kubectl get nodes 相同信息
    # 查看 pods 信息
    kubectl get pods -n kube-system

    coredns 状态为 Pending,这为正常情况,因为网络组件还未安装。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    NAME                                 READY   STATUS    RESTARTS   AGE
    coredns-7f74c56694-pq8hb 0/1 Pending 0 2m19s
    coredns-7f74c56694-xrzvv 0/1 Pending 0 2m19s
    etcd-k8s-master 1/1 Running 0 2m33s
    kube-apiserver-k8s-master 1/1 Running 0 2m32s
    kube-controller-manager-k8s-master 1/1 Running 0 2m32s
    kube-proxy-87wtl 1/1 Running 0 2m2s
    kube-proxy-klxr8 1/1 Running 0 109s
    kube-proxy-xn69c 1/1 Running 0 2m20s
    kube-scheduler-k8s-master 1/1 Running 0 2m32s

    安装网络组件

    网络是 kubernetes 的核心组成部分。

    由于是学习部署阶段,选择 flannel 作为 k8s 的网络组件。后期考虑单独学习 calico,由于此组件有更多的配置项,可以更容易满足生产条件。

    • 下载配置文件

      1
      2
      # 国内网络可能无法下载,下文会将详细的内容贴出
      wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
    • 修改配置文件
      根据注释内容进行修改,主要为添加网卡信息。

      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
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78
      79
      80
      81
      82
      83
      84
      85
      86
      87
      88
      89
      90
      91
      92
      93
      94
      95
      96
      97
      98
      99
      100
      101
      102
      103
      104
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
      170
      171
      172
      173
      174
      175
      176
      177
      178
      179
      180
      181
      182
      183
      184
      185
      186
      187
      188
      189
      190
      191
      192
      193
      194
      195
      196
      197
      198
      199
      200
      201
      202
      203
      204
      205
      206
      207
      208
      209
      210
      211
      212
      213
      214
      215
      216
      217
      218
      219
      220
      221
      222
      223
      224
      225
      226
      227
      228
      229
      230
      231
      232
      233
      234
      235
      236
      237
      238
      239
      240
      241
      242
      243
      244
      245
      246
      247
      248
      249
      ---
      apiVersion: policy/v1beta3 # 将v1beta1 修改为 v1beta3,不然会有警告,不修改也不影响使用。
      kind: PodSecurityPolicy
      metadata:
      name: psp.flannel.unprivileged
      annotations:
      seccomp.security.alpha.kubernetes.io/allowedProfileNames: docker/default
      seccomp.security.alpha.kubernetes.io/defaultProfileName: docker/default
      apparmor.security.beta.kubernetes.io/allowedProfileNames: runtime/default
      apparmor.security.beta.kubernetes.io/defaultProfileName: runtime/default
      spec:
      privileged: false
      volumes:
      - configMap
      - secret
      - emptyDir
      - hostPath
      allowedHostPaths:
      - pathPrefix: "/etc/cni/net.d"
      - pathPrefix: "/etc/kube-flannel"
      - pathPrefix: "/run/flannel"
      readOnlyRootFilesystem: false
      # Users and groups
      runAsUser:
      rule: RunAsAny
      supplementalGroups:
      rule: RunAsAny
      fsGroup:
      rule: RunAsAny
      # Privilege Escalation
      allowPrivilegeEscalation: false
      defaultAllowPrivilegeEscalation: false
      # Capabilities
      allowedCapabilities: ['NET_ADMIN', 'NET_RAW']
      defaultAddCapabilities: []
      requiredDropCapabilities: []
      # Host namespaces
      hostPID: false
      hostIPC: false
      hostNetwork: true
      hostPorts:
      - min: 0
      max: 65535
      # SELinux
      seLinux:
      # SELinux is unused in CaaSP
      rule: 'RunAsAny'
      ---
      kind: ClusterRole
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
      name: flannel
      rules:
      - apiGroups: ['extensions']
      resources: ['podsecuritypolicies']
      verbs: ['use']
      resourceNames: ['psp.flannel.unprivileged']
      - apiGroups:
      - ""
      resources:
      - pods
      verbs:
      - get
      - apiGroups:
      - ""
      resources:
      - nodes
      verbs:
      - list
      - watch
      - apiGroups:
      - ""
      resources:
      - nodes/status
      verbs:
      - patch
      ---
      kind: ClusterRoleBinding
      apiVersion: rbac.authorization.k8s.io/v1
      metadata:
      name: flannel
      roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: flannel
      subjects:
      - kind: ServiceAccount
      name: flannel
      namespace: kube-system
      ---
      apiVersion: v1
      kind: ServiceAccount
      metadata:
      name: flannel
      namespace: kube-system
      ---
      kind: ConfigMap
      apiVersion: v1
      metadata:
      name: kube-flannel-cfg
      namespace: kube-system
      labels:
      tier: node
      app: 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:
      name: kube-flannel-ds
      namespace: kube-system
      labels:
      tier: node
      app: flannel
      spec:
      selector:
      matchLabels:
      app: flannel
      template:
      metadata:
      labels:
      tier: node
      app: flannel
      spec:
      affinity:
      nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
      - matchExpressions:
      - key: kubernetes.io/os
      operator: In
      values:
      - linux
      hostNetwork: true
      priorityClassName: system-node-critical
      tolerations:
      - operator: Exists
      effect: NoSchedule
      serviceAccountName: flannel
      initContainers:
      - name: install-cni-plugin
      #image: flannelcni/flannel-cni-plugin:v1.0.1 for ppc64le and mips64le (dockerhub limitations may apply)
      image: rancher/mirrored-flannelcni-flannel-cni-plugin:v1.0.1
      command:
      - cp
      args:
      - -f
      - /flannel
      - /opt/cni/bin/flannel
      volumeMounts:
      - name: cni-plugin
      mountPath: /opt/cni/bin
      - name: install-cni
      #image: flannelcni/flannel:v0.17.0 for ppc64le and mips64le (dockerhub limitations may apply)
      image: rancher/mirrored-flannelcni-flannel:v0.17.0
      command:
      - cp
      args:
      - -f
      - /etc/kube-flannel/cni-conf.json
      - /etc/cni/net.d/10-flannel.conflist
      volumeMounts:
      - name: cni
      mountPath: /etc/cni/net.d
      - name: flannel-cfg
      mountPath: /etc/kube-flannel/
      containers:
      - name: kube-flannel
      #image: flannelcni/flannel:v0.17.0 for ppc64le and mips64le (dockerhub limitations may apply)
      image: rancher/mirrored-flannelcni-flannel:v0.17.0
      command:
      - /opt/bin/flanneld
      args:
      - --ip-masq
      - --kube-subnet-mgr
      - --iface=ens33 # 此处添加内网网卡名称
      resources:
      requests:
      cpu: "100m"
      memory: "50Mi"
      limits:
      cpu: "100m"
      memory: "50Mi"
      securityContext:
      privileged: false
      capabilities:
      add: ["NET_ADMIN", "NET_RAW"]
      env:
      - name: POD_NAME
      valueFrom:
      fieldRef:
      fieldPath: metadata.name
      - name: POD_NAMESPACE
      valueFrom:
      fieldRef:
      fieldPath: metadata.namespace
      - name: EVENT_QUEUE_DEPTH
      value: "5000"
      volumeMounts:
      - name: run
      mountPath: /run/flannel
      - name: flannel-cfg
      mountPath: /etc/kube-flannel/
      - name: xtables-lock
      mountPath: /run/xtables.lock
      volumes:
      - name: run
      hostPath:
      path: /run/flannel
      - name: cni-plugin
      hostPath:
      path: /opt/cni/bin
      - name: cni
      hostPath:
      path: /etc/cni/net.d
      - name: flannel-cfg
      configMap:
      name: kube-flannel-cfg
      - name: xtables-lock
      hostPath:
      path: /run/xtables.lock
      type: FileOrCreate
    • 安装 flannel

      1
      kubectl create -f kube-flannel.yml 
    • 查看 pods

      1
      kubectl get pods -n kube-system

      安装后需要等待一会儿,pods 会加载网络组件,待显示内容如下,即表示 kubernetes 安装完成

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      NAME                                 READY   STATUS    RESTARTS   AGE
      coredns-7f74c56694-pq8hb 1/1 Running 0 26m
      coredns-7f74c56694-xrzvv 1/1 Running 0 26m
      etcd-k8s-master 1/1 Running 0 26m
      kube-apiserver-k8s-master 1/1 Running 0 26m
      kube-controller-manager-k8s-master 1/1 Running 0 26m
      kube-flannel-ds-9kk96 1/1 Running 0 9m54s
      kube-flannel-ds-lldrp 1/1 Running 0 9m54s
      kube-flannel-ds-pmqxb 1/1 Running 0 9m54s
      kube-proxy-87wtl 1/1 Running 0 26m
      kube-proxy-klxr8 1/1 Running 0 26m
      kube-proxy-xn69c 1/1 Running 0 26m
      kube-scheduler-k8s-master 1/1 Running 0 26m

    其他支持的网络组件可参考官方文档。