创建kubernetes集群

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

1
2
3
4
5
6
7
修改为 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

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

2.1.2. 设置时钟同步

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

1
2
3
systemctl start chronyd.service

systemctl enable chronyd.service

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

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

如下

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

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

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

1
2
3

server CHRONY-SERVER-NAME-OR-IP iburst prefer

2.1.3. 主机名称解析

范围:master01, node01, node02

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

hostnamectl set-hostname <主机名>

1
2
3
4
5
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 服务通常只会安装并启动一种,在不确定具体启动状态的前提下,这里通过同时关闭并禁用二者即可简单达到设定目标。

1
2
3
4
5
6
7
8
9

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

1
2
3
4
5
6
#修改配置文件,永久禁用selinux, 防止重启导致selinux开启

vi /etc/sysconfig/selinux

SELINUX=disabled

1
2
3
4
# 禁用SELinux 立即生效

setenforce 0

2.1.6. 禁用 Swap 设备

范围:master01, node01, node02

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

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

1
2
3

swapoff -a

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

2.1.7. 启用 ipvs 内核模块

范围:master01, node01, node02

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#!/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

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

1
2
3
4
5

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 使用阿里云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 , 主要是一些网络组件相关的镜像
1
2
3
4
5
6
$sudo vi /etc/docker/daemon.json
{
"registry-mirrors": ["https://<你的ID>.mirror.aliyuncs.com"],
"live-restore": true,
"debug": true
}

镜像加速列表

提供者镜像地址
科大镜像https://docker.mirrors.ustc.edu.cn/
网易https://hub-mirror.c.163.com/
阿里云<https://<你的ID>.mirror.aliyuncs.com>
七牛云加速器https://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” 一行之后新增加一行内容如下:

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

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

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

设置为开机自启动

1
systemctl enable docker

确保默认使用桥接模式

1
2
3
$ 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 使其立即生效

1
2
3
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

内容如下:

1
2
3
4
5
6
7
8
9
10

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
1
2
3
4
5
6
7
# 更新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 节点要安装以下软件

1
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

并且要设置为开机启动

1
systemctl enable kubelet && systemctl start kubelet

说明:

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

3.2.3. 配置 kubelet

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

1
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. 初始化方式一
1
2
3
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 的值修改获取系统镜像时使用的镜像仓库。

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
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, 而后执行相应的命令:

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

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

1
2
3
4
5
6
7
8
9
10
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 为例:

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

vi 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
---

---
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

1
hostnamectl set-hostname k8s-node01

安装软件

1
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

并且要设置为开机启动

1
systemctl enable kubelet && systemctl start kubelet

下载 flannel 镜像

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

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

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

准备配置文件

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

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

mkdir /run/flannel/
1
2
3
4
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

1
kubeadm token create --print-join-command

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

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

设置开机启动

1

查看 node 状态

1
2
3
4
[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

1
hostnamectl set-hostname k8s-node02

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

1
kubeadm reset

重新加入集群

1
2
kubeadm join 192.168.1.71:6443 --token ud6ny7.9wzcg5du5zvrbbfv \
--discovery-token-ca-cert-hash sha256:dffb435eb20f133a8419bd406daf79cf6e4ee6af490xyzsd0ba95f610e5b1ec3
1
2
3
4
5
[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 安装
https://www.cnblogs.com/zhizihuakai/p/12629514.html
https://blog.csdn.net/llinyunxia/article/details/106160654?utm_medium=distribute.pc_relevant.none-task-blog-baidujs_title-0&spm=1001.2101.3001.4242