在CentOS7上部署单Master节点k8s集群(v1.15)

在虚拟机中的CentOS7集群中部署单master节点的k8s环境(v1.15)。

1、安装docker-ce

1.1 docker简介

最早的时候docker其实不是开源的,后来docker混得不太好,无奈之下创始人决定将docker开源(然后docker就火了),然后就有了docker这个开源项目,现在主要是由docker公司维护。

2017年年初,docker公司将原先的docker项目改名为moby,并创建了docker-ce和docker-ee。

这三者的关系是:

  • moby是继承了原先的docker的项目,是社区维护的的开源项目,谁都可以在moby的基础打造自己的容器产品

  • docker-ce( Community Edition)是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品

  • docker-ee( Enterprise Edition)是docker公司维护的闭源产品,是docker公司的商业产品。

我们这里还是使用docker-ce的稳定版本,关于ce版本其实也有三个分支:

我们来看一下官网的解释:

  • Stable gives you latest releases for general availability.
  • Test gives pre-releases that are ready for testing before general availability.
  • Nightly gives you latest builds of work in progress for the next major release.

简单的打个比方来说就是:Stable就是稳定版,Test就是开发版,Nightly就是内测版

1.2 安装docker-ce

centos版本的decker-ce官方安装指导:

https://docs.docker.com/install/linux/docker-ce/centos/

这里我们主要是通过yum的方式来安装,如果出现无法连接docker官网的情况,建议检查一下网络,或者使用rpm的方式进行安装。

1
2
3
4
5
6
7
# 导入官网提供的repo
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

# 安装docker及其相关组件
sudo yum install docker-ce docker-ce-cli containerd.io

注意这里我们需要校对一下密钥,确保和官网提供的无误。

1
2
3
4
5
6
7
8
# 启动docker
sudo systemctl start docker

# 跑个helloworld看看
sudo docker run hello-world

# 最后我们还要设置一下开机启动
sudo systemctl enable docker

2、准备工作

2.1 修改host文件(所有机器)

为了保证通信方便,每台主机上的/etc/hosts文件都需要进行修改,添加节点的IP地址hostname

同时最好把每台主机的hostname也修改成和上面的host文件一样。

1
2
3
4
5
# 可以直接编辑文件
vim /etc/hostname

# 或者使用命令
hostnamectl set-hostname

2.2 关闭防火墙(所有机器)

因为k8s涉及的端口非常多,我们先把防火墙关了,如果安装了iptable也先关掉。

1
2
3
# 关闭centos7自带的firewall防火墙
systemctl disable firewalld.service
systemctl stop firewalld.service

我们来看一下官网对这些端口的描述。

Master 节点

规则 方向 端口范围 作用 使用者
TCP Inbound 6443* Kubernetes API server All
TCP Inbound 2379-2380 etcd server client API kube-apiserver, etcd
TCP Inbound 10250 Kubelet API Self, Control plane
TCP Inbound 10251 kube-scheduler Self
TCP Inbound 10252 kube-controller-manager Self

Worker 节点

规则 方向 端口范围 作用 使用者
TCP Inbound 10250 Kubelet API Self, Control plane
TCP Inbound 30000-32767 NodePort Services** All

** NodePort 服务 的默认端口范围。

任何使用 * 标记的端口号都有可能被覆盖,所以您需要保证您的自定义端口的状态是开放的。

虽然主节点已经包含了 etcd 的端口,您也可以使用自定义的外部 etcd 集群,或是指定自定义端口。 您使用的 pod 网络插件 (见下) 也可能需要某些特定端口开启。由于各个 pod 网络插件都有所不同,请参阅他们各自文档中对端口的要求。

如果对安全性有要求,不放心关闭防火墙的话,最好还是修改一下防火墙的配置,放行这些端口。

2.3 同步时间(所有机器)

这里我们使用ntpdate来进行时间同步

1
2
3
4
5
6
7
8
# 使用yum安装ntpdate工具
yum install ntpdate -y

# 使用阿里云的源同步时间
ntpdate ntp1.aliyun.com

# 最后查看一下时间
hwclock

我们也可以在/etc/cron.hourly/下面直接新建一个文件,将ntpdate ntp1.aliyun.com这条命令写进去,这样cron就会每小时执行一次这个同步时间操作。关于cron可以点击这里了解。

1
2
3
cat >>/etc/cron.hourly/synctime <<EOF
ntpdate ntp1.aliyun.com
EOF

2.4 设置selinux(所有机器)

来自官网的说明,必须把selinux改为permissive(直接生效无需重启)或者disabled(需要重启生效)

通过命令 setenforce 0sed ... 可以将 SELinux 设置为 permissive 模式(将其禁用)。 只有执行这一操作之后,容器才能访问宿主的文件系统,进而能够正常使用 Pod 网络。您必须这么做,直到 kubelet 做出升级支持 SELinux 为止。

1
2
3
4
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# 也可以直接修改/etc/selinux/config文件

关于SELinux的简单介绍,可以点击这里查看之前的博客。

3、安装kubeadm, kubelet 和 kubectl

3.1 简介

我们需要在每台机器上都安装以下的软件包:

  • kubeadm: 用来初始化集群的指令。
  • kubelet: 在集群中的每个节点上用来启动 pod 和 container 等。
  • kubectl: 用来与集群通信的命令行工具。

kubeadm 不能 帮我们安装或管理 kubeletkubectl ,所以我们需要保证他们满足通过 kubeadm 安装的 Kubernetes 控制层对版本的要求。然而控制层与 kubelet 间的 小版本号 不一致无伤大雅,不过请记住 kubelet 的版本不可以超过 API server 的版本。例如 1.8.0 的 API server 可以适配 1.7.0 的 kubelet,反之就不行了。

3.2 添加yum仓库(所有机器)

由于众所周知的原因,k8s官网提供的yum源并不能在国内正常使用,好在我们还可以使用阿里的镜像源。

1
2
3
4
5
6
7
8
9
10
11
12
# 新建一个yum源
vim /etc/yum.repos.d/kubernetes.repo

# 添加下列内容到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
exclude=kube*

使用yum安装kubeadm, kubelet 和 kubectl

1
2
3
4
5
6
yum clean all
yum repolist

yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
# 启动kubelet并设置开机启动
systemctl enable kubelet && systemctl start kubelet

3.3 修改cgroup相关配置(所有机器)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
## Create /etc/docker directory.
mkdir /etc/docker

# Setup daemon.
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
EOF

mkdir -p /etc/systemd/system/docker.service.d

# Restart Docker
systemctl daemon-reload
systemctl restart docker

3.4 编辑环境变量(所有机器)

1
2
3
4
5
6
7
8
vim /etc/sysctl.conf
# 添加两行
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

sysctl -p
systemctl daemon-reload

3.5 关闭swap分区(所有机器)

1
2
3
4
5
6
7
swapoff -a

vim /etc/fstab
# 注释掉swap分区启动挂载的那一行

# 重启机器
reboot

3.6 拉取镜像

我们可以使用kubeadm config images pull看看需要拉取哪些镜像版本,然后根据错误提示来对下面的版本进行修改。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# https://hub.docker.com/r/mirrorgooglecontainers/kube-apiserver/tags
docker pull mirrorgooglecontainers/kube-apiserver:v1.15.0

# https://hub.docker.com/r/mirrorgooglecontainers/kube-proxy/tags
docker pull mirrorgooglecontainers/kube-proxy:v1.15.0

# https://hub.docker.com/r/mirrorgooglecontainers/kube-controller-manager/tags
docker pull mirrorgooglecontainers/kube-controller-manager:v1.15.0

# https://hub.docker.com/r/mirrorgooglecontainers/kube-scheduler/tags
docker pull mirrorgooglecontainers/kube-scheduler:v1.15.0

# https://hub.docker.com/r/mirrorgooglecontainers/etcd/tags
docker pull mirrorgooglecontainers/etcd:3.3.10

# https://hub.docker.com/r/mirrorgooglecontainers/pause/tags
docker pull mirrorgooglecontainers/pause:3.1

# https://hub.docker.com/r/mirrorgooglecontainers/kubernetes-dashboard-amd64/tags
docker pull mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.1

# https://hub.docker.com/r/coredns/coredns/tags
docker pull coredns/coredns:1.3.1

由于国内不能访问k8s官网,所以我们需要先使用docker拉取镜像,然后使用tag对其更改名称。

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
# 拉取docker上的镜像到本地
# https://hub.docker.com/r/mirrorgooglecontainers/kube-apiserver/tags
docker pull mirrorgooglecontainers/kube-apiserver:v1.15.0
# https://hub.docker.com/r/mirrorgooglecontainers/kube-proxy/tags
docker pull mirrorgooglecontainers/kube-proxy:v1.15.0
# https://hub.docker.com/r/mirrorgooglecontainers/kube-controller-manager/tags
docker pull mirrorgooglecontainers/kube-controller-manager:v1.15.0
# https://hub.docker.com/r/mirrorgooglecontainers/kube-scheduler/tags
docker pull mirrorgooglecontainers/kube-scheduler:v1.15.0
# https://hub.docker.com/r/mirrorgooglecontainers/etcd/tags
docker pull mirrorgooglecontainers/etcd:3.3.10
# https://hub.docker.com/r/mirrorgooglecontainers/pause/tags
docker pull mirrorgooglecontainers/pause:3.1
# https://hub.docker.com/r/mirrorgooglecontainers/kubernetes-dashboard-amd64/tags
docker pull mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.1
# https://hub.docker.com/r/coredns/coredns/tags
docker pull coredns/coredns:1.3.1


# 使用tag对其改名,方便kubeadm直接拉取使用
docker tag mirrorgooglecontainers/kube-apiserver:v1.15.0 k8s.gcr.io/kube-apiserver:v1.15.0
docker tag mirrorgooglecontainers/kube-proxy:v1.15.0 k8s.gcr.io/kube-proxy:v1.15.0
docker tag mirrorgooglecontainers/kube-controller-manager:v1.15.0 k8s.gcr.io/kube-controller-manager:v1.15.0
docker tag mirrorgooglecontainers/kube-scheduler:v1.15.0 k8s.gcr.io/kube-scheduler:v1.15.0
docker tag mirrorgooglecontainers/etcd:3.3.10 k8s.gcr.io/etcd:3.3.10
docker tag mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1
docker tag mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.1 k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
docker tag coredns/coredns:1.3.1 k8s.gcr.io/coredns:1.3.1


# 删除掉多余的images
docker rmi mirrorgooglecontainers/kube-apiserver:v1.15.0
docker rmi mirrorgooglecontainers/kube-proxy:v1.15.0
docker rmi mirrorgooglecontainers/kube-controller-manager:v1.15.0
docker rmi mirrorgooglecontainers/kube-scheduler:v1.15.0
docker rmi mirrorgooglecontainers/etcd:3.3.10
docker rmi mirrorgooglecontainers/pause:3.1
docker rmi mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.1
docker rmi coredns/coredns:1.3.1

最后效果如下

3.7 初始化master节点

  • --kubernetes-version就是我们这里使用的k8s版本

  • --apiserver-advertise-address 指明用Master的哪个interface与Cluster的其他节点通信。如果Master有多个interface,建议明确指定,如果不指定,kubeadm会自动选择有默认网关的interface

  • --pod-network-cidr 指定Pod网络的范围。Kubernetes支持多种网络方案,而且不同网络方案对–pod-network-cidr有自己的要求,这里设置为10.244.0.0/16是因为我们将使用flannel网络方案,必须设置成这个CIDR

1
kubeadm init --kubernetes-version=v1.15.0 --apiserver-advertise-address 192.168.100.50 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12

注意红框中的那一串密钥要保存好,后面我们添加节点的时候需要用到。

3.8在master上配置kubectl

注意这里要切换到普通用户而不能使用root用户!

注意这里要切换到普通用户而不能使用root用户!

注意这里要切换到普通用户而不能使用root用户!

1
2
3
4
5
6
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g)
$HOME/.kube/config
# 多加一个kubectl的自动补全动能方便我们使用
echo "source <(kubectl completion bash)" >> ~/.bashrc

到这里我们检查一下是否安装顺利

1
2
3
4
# 获取集群状态
kubectl get cs
# 获取集群节点信息
kubectl get nodes

4、安装flannel网络(Master)

安装flannel

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

到这里master节点上面的操作就算是完成了

1
2
3
4
# 查看pod运行情况
kubectl get pods -n kube-system
# 查看并验证节点信息是否成功
kubectl get nodes

5、添加node

在node节点上使用root用户运行下列命令将node节点加入到集群中,下面的密钥就是刚刚前面生成的密钥,而这个192.168.100.50:6443就是master节点的IP地址和对应端口。

1
kubeadm join --token 3pyvba.siol4xy1rvf2om8k --discovery-token-ca-cert-hash sha256:c61cdd8b8ad5d34faece61867e76d539dbc243c1f206eacbab163895777c099e 192.168.100.50:6443

最后顺利启动之后应该是如下图所示

提示:

如果node节点上没有顺利出现running的话,很有可能是因为镜像被墙了无法顺利拉取镜像,这时我们需要按照步骤3.6中的操作来手动拉取镜像。

查看pod运行情况的命令

1
kubectl describe pod <PodName> --namespace=<namespace>

输出内容太长了,这里只截取一部分。