创建kubernetes集群

60 阅读15分钟

1. 前言

本文主要讲述配置一个最简单的 k8s 集群, 本集群由 1 个 master(master01) 和 2 个 node 节点(node01, node02)组成. 当前(2021/02/15) kubernetes 的最新稳定版本为 v1.20.2. 但是我依然采用的是较老的版本 v1.13.2, 因为众多参考文档使用的是这个版本,目前不清楚各组件之间的版本兼容性问题,所以依然采用这个版本,后续经过多次重复安装,验证各版本的兼容性后再回头来更新版本信息。另外网上有很多的 k8s 实验平台, 只需轻松几个点击, 就可以搭建 k8s 集群, 如果只是学习目的, 可以跳过这唬人的安装过程, 直接进入概念学习阶段, 等对 k8s 玩得很溜了再回头来搭建环境. 欲练此功, 不安装 k8s 也可以. 这里推荐play-with-k8s.com, 创建过程可参考这篇文章只要有 github 账号即可以登录使用.

2. 部署工具介绍

部署工具和部署环境有很多种选项

  • 常用的部署环境: IaaS 公有云环境:AWS, GCE, Azure,阿里云等; Iaas 私有云环境: OpenStack 和 vSphere 等; Baremetal 环境(裸金属环境):物理服务器或独立的虚拟机等;

  • 常用部署工具: kubeadm kops kubespray Kontena Pharos

  • 其它更完善的二次封装的常用发行版 Rancher (Labs) Tectonic (CoreOS) Openshift (Redhat)

本文主要讲述选择使用 kubeadm 采用 docker 镜像安装,目的是为了更好的掌握 kubernetes 深层次的概念和运行机制。 主机规划:

主机名虚拟机类型系统配置网络
master01VirtualBoxCentos7.92U2GB SATA:100GBIP:192.168.1.71
node01VirtualBoxCentos7.92U2GB SATA:50GBIP:192.168.1.61
node01VirtualBoxCentos7.92U2GB SATA:50GBIP: 192.168.162

2.1. 环境要求

各主机(master01, node01, node02)所需的环境如下:

(1) 借助于 NTP 服务设定各节点时间精确同步;

(2) 借助 DNS 完成各节点的主机名称解析,测试环境主机较少时可以使用 hosts 文件进行名称解析;

(3)关闭主机的 iptables 或 firewall 服务,并确保它们被禁止随系统引导过程启动; (4)各主机禁用 SELinux;

(5) 各节点禁用所有 Swap 设备

(6)若要使用 ipvs 模型的 proxy, 各节点还需要载入 ipvs 相关的各模块

2.1.1. 设置各主机 ip

首先将虚拟机设置为桥接模式
在 x86 架构上安装 CentOs7 最小安装时,默认 ip 地址设置为 ipv6,如果需要设置为 ipv4,需要进行如下设置。 首先确定以 enp 打头的网卡
/etc/sysconfig/network-scripts/ifcfg-enp8s0

修改为 IPV6INIT=no
BOOTPROTO="static"         # 使用静态IP地址,默认为dhcp
IPADDR="192.168.1.71"   # 设置的静态IP地址
NETMASK="255.255.255.0"    # 子网掩码
GATEWAY="192.168.1.1"    # 网关地址
DNS1="192.168.1.1"       # DNS服务器
ONBOOT=yes

修改 /etc/resolv.conf

# 添加域名解析服务
nameserver 192.168.1.1
  # 修改后立即重启网络服务,使其生效
systemctl restart network

2.1.2. 设置时钟同步

范围:master01, node01, node02 若各节点可直接访问互联网,直接启动 chronyd 系统服务,并设定为开机启动

systemctl start chronyd.service

systemctl enable chronyd.service

时钟同步后和主机不一致的解决办法 第一检查

ls -ltr /etc/localtime
#如果不是上海,则修改localtime
lrwxrwxrwx. 1 root root 38 Jun 19  2020 /etc/localtime -> ../usr/share/zoneinfo/America/New_York

如下

1、vi /etc/sysconfig/clock #编辑文件
ZONE="Asia/Shanghai"
UTC=false #设置为false,硬件时钟不与utc时间一致
ARC=false

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime #linux的时区设置为上海
systemctl restart chronyd.service
/sbin/hwclock --systohc #设置硬件时间和系统时间一致并校准

不过,建议用户配置使用本地的时间服务器,在节点数量众多时尤其如此。 存在可用的时间服务器时,修改节点的/etc/chrony.conf 配置文件,并将时间服务器指向相应的主机即可, 配置格式如下:


server CHRONY-SERVER-NAME-OR-IP iburst

2.1.3. 主机名称解析

范围:master01, node01, node02

出于简化配置步骤的目的,本教程使用 hosts 文件进行各节点名称解析,文件内容如下所示:

hostnamectl set-hostname <主机名>

vi /etc/hosts
#添加内容如下
192.168.1.71 master01.ilinux.io master01 k8s-master k8s-master.ilinux.io
192.168.1.61 node01.ilinux.io node01 k8s-node01 k8s-node01.ilinux.io
192.168.1.62 node02.ilinux.io node02 k8s-node02 k8s-node02.ilinux.io

2.1.4. 关闭 iptables 或 firewalld 服务

范围:master01, node01, node02

在 centos7 上, iptables 或 firewalld 服务通常只会安装并启动一种,在不确定具体启动状态的前提下,这里通过同时关闭并禁用二者即可简单达到设定目标。


systemctl stop firewalld.service

systemctl stop iptables.service

systemctl disable firewalld.service

systemctl disable iptables.service

2.1.5. 关闭并禁用 SELinux

范围:master01, node01, node02

修改 /etc/sysconfig/selinux 文件,将 SELINUX 配置设置为 disabled

#修改配置文件,永久禁用selinux, 防止重启导致selinux开启

vi /etc/sysconfig/selinux

SELINUX=disabled

# 禁用SELinux 立即生效

setenforce 0

2.1.6. 禁用 Swap 设备

范围:master01, node01, node02

部署集群时,kubeadm 默认会预先检查当前主机是否禁用了 swap 设备,并在未禁用时强制终止部署过程。因此,在主机内存资源充裕的条件下,需要禁用所有的 Swap 设备,否则,就需要在后文的 kubeadm init 及 kubeadm join 命令执行时额外使用相关的选项忽略检查错误。

关闭 Swap 设备,需要分两步。首先关闭当前已启用的所有 Swap 设备:


swapoff -a

然后编辑/etc/fstab 配置文件,注释掉 swap 设备的挂载项(永久关闭 swap 分区)

2.1.7. 启用 ipvs 内核模块

范围:master01, node01, node02

创建内核模块载入相关的脚本文件/etc/sysconfig/modules/ipvs.modules, 设定自动载入的内核模块。文件内容如下:

#!/bin/bash

ipvs_mods_dir="/usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs"

for mod in $(ls $ipvs_mods_dir | grep -o "^[^.]*"); do

    /sbin/modinfo -F filename $mod &> /dev/null

    if [ $? -eq 0 ]; then

        /sbin/modprobe $mod

    fi
done

修改文件权限,并手动为当前系统加载内核模块


chmod +x /etc/sysconfig/modules/ipvs.modules

bash /etc/sysconfig/modules/ipvs.modules

3. 安装程序包(在各主机上完成如下设定)

3.1. 安装 docker (master01, node01 & node02)

安装 docker 之前要确定 docker 版本是否在 kubernetes 相应版本支持列表里面,以避免遇到版本兼容性问题的坑,这里 列出了部分 kubernetes 版本与 docker 版本的兼容信息,希望对你的集群环境搭建有帮助。

3.1.1. 配置 docker-ce yum 源

范围:master01, node01, node02

# 使用阿里云yum源
sudo curl https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo
sudo sed -i 's+download.docker.com+mirrors.aliyun.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 或者华为云yum源,两者选其一
sudo wget -O /etc/yum.repos.d/docker-ce.repo https://repo.huaweicloud.com/docker-ce/linux/centos/docker-ce.repo
sudo sed -i 's+download.docker.com+repo.huaweicloud.com/docker-ce+' /etc/yum.repos.d/docker-ce.repo

# 更新yum源缓存
sudo yum makecache fast
#选择合适的版本
yum list docker-ce --showduplicates | sort -r

#安装指定版本
sudo yum -y install docker-ce-18.03.1.ce-1.el7.centos.x86_64

3.1.2. 配置 docker

3.1.2.1. 配置镜像加速

由于 dockerhub 镜像仓库在国外,访问速度较慢,下载镜像的过程中,多数情况下会因为超时而失败,所以强烈建议配置镜像加速。 另外在整个安装过程中主要需要与 internet 上三个镜像仓库打交道

  1. DockerHub,
  2. gcr.io 这个几乎不能访问,后面会介绍到如何获得其上相应的镜像
  3. quay.io , 主要是一些网络组件相关的镜像
$sudo vi /etc/docker/daemon.json
{
    "registry-mirrors": ["https://<你的ID>.mirror.aliyuncs.com"],
    "live-restore": true,
    "debug": true
}

镜像加速列表

提供者镜像地址
科大镜像docker.mirrors.ustc.edu.cn/
网易hub-mirror.c.163.com/
阿里云<https://<你的ID>.mirror.aliyuncs.com>
七牛云加速器reg-mirror.qiniu.com
daocloud 加速器<http://<你的ID>.m.daocloud.io/>

其他还有华为云镜像加速,显然是为华为云用户准备的,请参考这篇文章进行配置镜像加速

3.1.2.2. docker iptables FORWARD 策略

docker 自 1.13 版起会自动设置 iptables 的 FORWARD 默认策略为 DROP,这可能会影响 kubernetes 集群依赖的报文转发功能,因此,需要在 docker 服务启动后,重新将 FORWARD 链的默认策略设置为 ACCEPT,方式是修改/usr/lib/systemd/system/docker.service 文件,在 “ExecStart=/usr/bin/dockerd” 一行之后新增加一行内容如下:

    ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT

重载完成后即可启动 docker 服务:

# 重新加载docker服务设置
systemctl daemon-reload
# 重启docker服务
systemctl start docker

设置为开机自启动

  systemctl enable docker

确保默认使用桥接模式

$ sudo sysctl -a | grep bridge
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

如果不是桥接模式(等号后面为 0), 手动修改这两个参数 方法 1: 修改/etc/sysctl.conf 添加以上两个参数

方法 2: 在 /etc/sysctl.d 中添加一个以 conf 为后缀的文件例如 k8s.conf,将以上两项配置添加进去

手动执行 sysctl -p /etc/sysctl.conf 或者 sysctl -p /etc/sysctl.d/k8s.conf 使其立即生效

net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

3.2. 安装  kubelet (master01)

范围:master01, node01, node02

3.2.1. 配置 kubernetes yum 源

创建 /etc/yum.repos.d/kubernetes.repo

内容如下:


cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[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源缓存
 sudo yum -y makecache fast
#检查版本,选择合适的版本
yum list kubeadm --showduplicates | sort -r
yum list kubelet --showduplicates | sort -r
yum list kubectl --showduplicates | sort -r
yum list kubernetes-cni --showduplicates | sort -r

3.2.2. 安装 kubelet

master 和 node 节点要安装以下软件

sudo yum install -y kubeadm-1.18.2-0.x86_64 kubelet-1.18.2-0.x86_64 kubectl-1.18.2-0.x86_64 kubernetes-cni-0.8.7-0.x86_64

并且要设置为开机启动

systemctl enable kubelet && systemctl start kubelet

说明:

  • kubelet 为 Kubernetes 的核心守护进程之一,负责将配置清单运行为容器(Pod)
  • Kubeadm 相当于部署集群本身的一个工具,用于简化集群的安装工作,负责根据配置文件部署集群,升级集群等等工作。
  • kubectl 相当于集群的客户端,负责和集群的 API 组件交互,比如查询 node 的状态,容器的运行情况,以及提交任务等等。

3.2.3. 配置 kubelet

如果未禁用 swap 设备,则需要编辑 kubelet 的配置文件/etc/sysconfig/kubelet, 设置忽略 Swap 启用的状态错误, 内容如下:

KUBELET_EXTRA_ARGS="--fail-swap-on=false"

4. 配置 Master 和 Nodes

components 规划

主机名组件备注
master01kubelet (yum 安装) kubadm (yum 安装) kubectl(yum 安装) docker  (yum 安装) kube-apiserver (Pod)kube-scheduler (Pod) kub-controller-manager (Pod) cni (flannel Pod) etcd  (Pod) kube-proxy (Pod)
node01kubelet (yum 安装) docker (yum 安装) cni (flannel Pod) kube-proxy (Pod)
node02kubelet (yum 安装) docker (yum 安装) cni (flannel Pod) kube-proxy (Pod)

4.1. 插件安装

Metrics-Server(Pod) Dashboard (Pod) CoreDNS (Pod) EFK (Pod) Prometheus (Pod) Ingress-Controller (Pod)

4.2. 配置 master 节点

4.2.1. 拉取必要的镜像

说明:k8s.gcr.io 上的镜像由于无法描述的原因,在国内无法直接拉取。但是阿里云 registry 中共享了相应版本的 kubernetes 镜像,这里再次感谢阿里的无私贡献,敬佩阿里的企业文化(利他),不仅免费,还有消耗阿里云的大量带宽。由于 docker 镜像命名规范的原因,拉取下来后要重新打 tag 才能使用,以下脚本包含了拉取镜像,更名,清理的功能。本人把安装文档写得足够详细,向阿里致敬!

kubeadm init --kubernetes-version=1.18.1 --apiserver-advertise-address=192.168.1.71 --image-repository registry.aliyuncs.com/google_containers --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16

注意修改 apiserver-advertise-address 为 master 节点 ip 参数解释: –kubernetes-version: 用于指定 k8s 版本; –apiserver-advertise-address:用于指定 kube-apiserver 监听的 ip 地址,就是 master 本机 IP 地址。 –pod-network-cidr:用于指定 Pod 的网络范围; 10.244.0.0/16 –service-cidr:用于指定 SVC 的网络范围; –image-repository: 指定阿里云镜像仓库地址

这一步很关键,由于 kubeadm 默认从官网 k8s.grc.io 下载所需镜像,国内无法访问,因此需要通过–image-repository 指定阿里云镜像仓库地址

4.2.2. 初始化 master

kubeadm init 命令支持两种初始化方式, 一是通过命令行选项传递关键部署设定,另一种是基于 yaml 格式的 kubeadm 专用配置文件,后一种运行用户自定义各种部署参数。下面分别给出了两种实现方式的配置步骤,建议读者采用第二种方式进行。

4.2.2.1. 初始化方式一
 systemctl enable kubelet.service
 systemctl start kubelet.service
 kubeadm init --kubernetes-version=v1.13.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --ignore-preflight-errors=Swap

命令中的各选项说明:
(1)--kubernetes-version 选项的版本号用于指定要部署的 kubernetes 程序版本,它需要与预拉取的 kubernetes 镜像版本一致参考脚本变量(K8S_VERSION)
(2)--pod-network-cidr 选项用于指定 pod 网络的网段,它通常应该与要部署使用的网络插件(例如 flannel, calico 等)的默认设定保持一致, 10.244.0.0/16 是 flannel 默认使用的网络;
(3)--service-cidr 用于指定为 Service 分配使用的网络地址,它由 kubernetes 管理, 默认即为 10.96.0.0/12
(4)最后一个选项 --ignore-preflight-errors=Swap 防止未禁用 swap 设备而导致初始化失败,生产环境建议关闭 swap 设备,已获得更好的性能,请参考前述禁用 swap 分区进行设定。
(5)这里需要读者对 kubernetes 的三层网(node 网络,pod 网络,service 网络)知识有所了解,再来做相关参数的调整。

4.2.2.2. 初始化方式二

kubeadm 也可以通过配置文件加载配置, 以定制更丰富的部署选项。以下是符合前述命令设定方式的使用示例,不过,它明确定义了 kubeProxy 的模式为 ipvs, 并支持通过修改 imageRepository 的值修改获取系统镜像时使用的镜像仓库。

apiVersion: kubeadm.k8s.io/v1alpha2
kind: MasterConfiguration
kubernetesVersion: v1.13.2
api:
    advertiseAddress: 192.168.1.71
    bindPort: 6443
    controlPlaneEndpoint: ""
imageRepository: k8s.gcr.io
kubeProxy:
    config:
        mode: "ipvs"
        ipvs:
            ExcludeCIDRs: null
            minSyncPeriod: 0s
            scheduler: ""
            syncPeriod: 30s
kubeletConfiguration:
    baseConfig:
        cgroupDriver: cgroupfs
        clusterDNS:
        - 10.96.0.10
        clusterDomain: cluster.local
        failSwapOn: false
        resolvConf: /etc/resolv.conf
        staticPodPath: /etc/kubernetes/manifests
networking:
    dnsDomain: cluster.local
    podSubnet: 10.244.0.0/16
    serviceSubnet: 10.96.0.0/12

将上面的内容保存于配置文件中, 例如 kuberadm-config.yaml, 而后执行相应的命令:

    # kubeadm init --config kubeadm-config.yaml --ignore-prelight-errors=Swap

注意:对于 kubernetes 系统的新用户来说,无论使用上述哪种方式,命令运行结束后,请记录最后的 kubeadm join 命令输出的最后提示的操作步骤。 下面的内容是需要用户记录的一个命令输出示例,它提示了后续需要操作的步骤:

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

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/
  you can now join any number of machines by running the following on each node as root:
kubeadm join 172.168.0.70:6443 --token uoutlc.aknhy63zioieuw9x --discovery-toke-ca-cert-hash sha256:cd8bd32c9be6c88573c56f

接下来要部署一个 podnetwork addon 以 flannel 为例:

  kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

vi kube-flannel.yml

---

---
apiVersion: policy/v1beta1
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
        image: quay.io/coreos/flannel:v0.13.1-rc2
        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: quay.io/coreos/flannel:v0.13.1-rc2
        command:
        - /opt/bin/flanneld
        args:
        - --ip-masq
        - --kube-subnet-mgr
        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
        volumeMounts:
        - name: run
          mountPath: /run/flannel
        - name: flannel-cfg
          mountPath: /etc/kube-flannel/
      volumes:
      - name: run
        hostPath:
          path: /run/flannel
      - name: cni
        hostPath:
          path: /etc/cni/net.d
      - name: flannel-cfg
        configMap:
          name: kube-flannel-cfg

注意:kubernetes 本身没有 pod 网络创建和管理功能,其本身只提供了一组依赖网络组件的接口,网络功能一般有第三方插件完成,比如 flannel, calico 等等。但是 Kubernetes 本身集成了 service 网络的管理功能,其底层实际是创建一系列 iptables 或 ipvs 规则来完成的。

部署完之后查看 kubernetes 相关的容器 coredns etcd kube-apiserver kuber-controller kube-flannel-ds-amd64-bbnz2 kube-proxy kube-scheduler

4.3. 配置第一个 node 节点, 并添加到集群

修改 ip 地址 修改主机名部分,改为 k8s-node01

hostnamectl set-hostname k8s-node01

安装软件

sudo yum install -y kubeadm-1.18.2-0.x86_64 kubelet-1.18.2-0.x86_64 kubectl-1.18.2-0.x86_64 kubernetes-cni-0.8.7-0.x86_64

并且要设置为开机启动

systemctl enable kubelet && systemctl start kubelet

下载 flannel 镜像

docker pull registry.cn-hangzhou.aliyuncs.com/daoh/flannel:v0.12.0-amd64

为镜像打 tag,保持和 yaml 文件一样。

docker tag registry.cn-hangzhou.aliyuncs.com/daoh/flannel:v0.12.0-amd64 quay.io/coreos/flannel:v0.12.0-amd64

准备配置文件

mkdir -p /etc/cni/net.d/
vi /etc/cni/net.d/10-flannel.conf
{"name":"cbr0","type":"flannel","delegate": {"isDefaultGateway": true}}

mkdir -p /usr/share/oci-umount/oci-umount.d

mkdir /run/flannel/
mkdir ~/k8s
cd k8s
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml

在 master 上查询 join string

kubeadm token create --print-join-command

在 node 上执行查询结果, 加入集群

kubeadm join 192.168.1.71:6443 --token ud6ny7.9wzcg5du5zvrbbfv \
--discovery-token-ca-cert-hash sha256:dffb435eb20f133a8419bd406daf79cf6e4ee6af490xyzsd0ba95f610e5b1ec3

设置开机启动

查看 node 状态

[root@node01 k8s]# kubectl get nodes
NAME         STATUS   ROLES    AGE     VERSION
k8s-master   Ready    master   45h     v1.18.2
k8s-node01   Ready    <none>   5m52s   v1.18.2

4.4. 配置第二个 node 节点, 并添加到集群

修改 ip 地址
vi /etc/sysconfig/network-scripts/ifcfg-enp0s3 修改 ip 地址
修改主机名部分,改为 k8s-node02

hostnamectl set-hostname k8s-node02

重新启动 重新登录 node2 重新初始化节点配置, 执行命令

kubeadm reset

重新加入集群

kubeadm join 192.168.1.71:6443 --token ud6ny7.9wzcg5du5zvrbbfv \
--discovery-token-ca-cert-hash sha256:dffb435eb20f133a8419bd406daf79cf6e4ee6af490xyzsd0ba95f610e5b1ec3
[root@k8s-node02 ~]# kubectl get nodes
NAME         STATUS   ROLES    AGE    VERSION
k8s-master   Ready    master   45h    v1.18.2
k8s-node01   Ready    <none>   31m    v1.18.2
k8s-node02   Ready    <none>   4m3s   v1.18.2

5. 问题排查 troubleshooting

在 k8s 中,大部分的问题,都能通过 logs 和 describe 两个命令进行分析和定位

6. 后记

本技术博客原创文章位于鹏叔的技术博客空间 - 创建 kubernetes 集群, 要获取最近更新请访问原文.

更多技术博客请访问: 鹏叔的技术博客空间

7. 参考文档

kubernetes 官方网站

Kubernetes github

k8s 记录-国内下载 k8s 组件镜像

Kubernetes 1.20 版本开始不推荐使用 Docker,你知道吗

Kubernetes 各版本对应支持的 docker 版本列表

k8s 不再支持 docker_k8s 不支持 Docker 了? 别慌!官方最新解释来了…

[Which kubernetes version is supported in docker version 18.09] 单机版 kubernetes 1.18.2 安装 www.cnblogs.com/zhizihuakai… blog.csdn.net/llinyunxia/…