关于 Kubernetes 系列其他文章的传送门
-
《 部署 Kubernetes 也能如此简单吗? 》 您当前所在位置

一、主机环境预设¶
Kubernetes 技术已经成为了原生云技术的事实标准,它是目前基础软件领域最为热门的分布式调度和管理平台。于是,Kubernetes 也几乎成了时下开发工程师和运维工程师必备的技能之一。
测试环境基准¶
测试使用的 Kubernetes 集群可由一个 master 主机及一个以上(建议至少两个)node 主机组成,这些主机可以是物理服务器,也可以运行于 vmware、virtualbox 或 kvm 等虚拟化平台上的虚拟机,甚至是公有云上的 VPS 主机。
本测试环境将由 master01、node01 和 node02 三个独立的主机组成,它们分别拥有 4 核心的 CPU 及 4G 的内存资源,操作系统环境均为 CentOS 7.5 1804,域名为 ilinux.io。此外,各主机需要预设的系统环境如下:
- 借助于 chrony 服务设定各节点时间精确同步;
- 通过 DNS 完成各节点的主机名称解析,测试环境主机数量较少时也可以使用 hosts 文件进行;
- 关闭各节点的 iptables 或 firewalld 服务,并确保它们被禁止随系统引导过程启动;
- 各节点禁用 SELinux;
- 各节点禁用所有的 Swap 设备;
- 若要使用 ipvs 模型的 proxy,各节点还需要载入 ipvs 相关的各模块。
1、设定时钟同步¶
若节点可直接访问互联网,直接启动 chronyd 系统服务,并设定其随系统引导而启动。
1 | systemctl start chronyd.service |
不过,建议用户配置使用本地的的时间服务器,在节点数量众多时尤其如此。存在可用的本地时间服务器时,修改节点的 /etc/crhony.conf 配置文件,并将时间服务器指向相应的主机即可,配置格式如下:
1 | server CHRONY-SERVER-NAME-OR-IP iburst |
2、主机名称解析¶
出于简化配置步骤的目的,本测试环境使用 hosts 文件进行各节点名称解析,文件内容如下所示:
1 | 172.20.0.71 master01.ilinux.io master01 |
3、关闭 iptables 或 firewalld 服务¶
在 CentOS7 上,iptables 或 firewalld 服务通常只会安装并启动一种,在不确认具体启动状态的前提下,这里通过同时关闭并禁用二者即可简单达到设定目标。
1 | systemctl stop firewalld.service |
4、关闭并禁用 SELinux¶
若当前启用了 SELinux,则需要编辑 /etc/sysconfig/selinux 文件,禁用 SELinux,并临时设置其当前状态为 permissive:
1 | sed -i 's@^\(SELINUX=\).*@\1disabled@' /etc/sysconfig/selinux |
5、禁用 Swap 设备¶
部署集群时,kubeadm 默认会预先检查当前主机是否禁用了 Swap 设备,并在未禁用时强制终止部署过程。因此,在主机内存资源充裕的条件下,需要禁用所有的 Swap 设备,否则,就需要在后文的 kubeadm init 及 kubeadm join 命令执行时额外使用相关的选项忽略检查错误。
关闭 Swap 设备,需要分两步完成。首先是关闭当前已启用的所有 Swap 设备:
1 | swapoff -a |
而后编辑 /etc/fstab 配置文件,注释用于挂载 Swap 设备的所有行。
6、启用 ipvs 内核模块¶
创建内核模块载入相关的脚本文件 /etc/sysconfig/modules/ipvs.modules,设定自动载入的内核模块。文件内容如下:
1 | !/bin/bash |
修改文件权限,并手动为当前系统加载内核模块:
1 | chmod +x /etc/sysconfig/modules/ipvs.modules |
二、安装程序包¶
注意:在各主机上完成如下设定
1、生成 yum 仓库配置¶
均使用阿里云的镜像站。
首先获取 docker-ce 的配置仓库配置文件:
1 | wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker.repo |
而后手动生成 kubernetes 的 yum 仓库配置文件 /etc/yum.repos.d/kubernetes.repo,内容如下:
1 | cat <<EOF > /etc/yum.repos.d/kubernetes.repo |
2、安装相关的程序包¶
Kubernetes 会对经过充分验正的 Docker 程序版本进行认证,在 k8s 官方的发布页可以查到相关信息。目前认证完成的最高版本是 17.03,但 docker-ce 的最新版本已经高出了几个版本号。管理员可忽略此认证而直接使用最新版本的 docker-ce 程序。不过,还是建议使用经过验证的 Docker 版本。
安装最新版:
1 | yum install docker-ce |
如果要安装目前经过 Kubernetes 认证的 docker-17 17.03 版,可以将上面第一条安装命令替换为如下命令:
1 | yum install -y --setopt=obsoletes=0 docker-ce-17.03.2.ce docker-ce-selinux-17.03.2.ce |
三、启动 docker 服务¶
注意:在各主机上完成如下设定
代理¶
若要通过默认的 k8s.gcr.io 镜像仓库获取 Kubernetes 系统组件的相关镜像,需要配置 docker Unit File 文件:
- 在
/usr/lib/systemd/system/docker.service中的Environment变量,为其定义能用的HTTPS_PROXY,格式如下:
1 | Environment="HTTPS_PROXY=PROTOCOL://HOST:PORT" |
实际使用:
1 | Environment="HTTPS_PROXY=http://www.ik8s.io:10070" |
更改 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¶
重载完成后即可启动 docker 服务:
1 | systemctl daemon-reload |
而后设定 docker 和 kubelet 随系统引导自动启动:
1 | systemctl enable docker kubelet |
保证在 sysctl 的配置中关于桥接的部分,被设为 1
1 | cat <<EOF > /etc/sysctl.d/k8s.conf |
使用 Docker info 命令可验证,如设定不对会有报错提示。
四、初始化主节点¶
注意:只在 master01 节点上完成如下操作
1、初始化 master 节点¶
若未禁用 Swap 设备,则需要编辑 kubelet 的配置文件 /etc/sysconfig/kubelet,设置其忽略 Swap 启用的状态错误,内容如下:
1 | KUBELET_EXTRA_ARGS="--fail-swap-on=false" |
(可选步骤)而后,在运行初始化命令之前先运行如下命令单独获取相关的镜像文件,而后再运行后面的 kubeadm init 命令,以便于观察到镜像文件的下载过程。
1 | kubeadm config images pull |
最后就可以通过 kubeadm init 命令进行 master 节点的初始化了,支持两种初始化方式:
- 通过命令行选项传递关键的部署设定;
- (建议)基于 yaml 格式的专用配置文件,这种允许用户自定义各个部署参数。
下面分别给出了两种实现方式的配置步骤。
建议读者采用第二种方式进行。
另外,kubeadm init 命令完整参考指南请移步官方文档。
https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/。
注意事项¶
对于 Kubernetes 系统的新用户来说,无论使用哪种方法初始化,命令运行结束后,请另外新建一个文本文件,记录最后输出的 kubeadm join ...... 命令,因为它提示了后续需要的操作步骤,类似这样:
1 | Your Kubernetes master has initialized successfully! |
初始化方式一¶
运行如下命令完成 master01 节点的初始化:
1 | kubeadm init --kubernetes-version=v1.13.3 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --ignore-preflight-errors=Swap |
可使用 --dry-run 测试安装一下。
命令中的各选项简单说明如下:
--kubernetes-version:此选项的版本号用于指定要部署的 Kubenretes 程序版本,它需要与当前安装的 kubeadm 版本保持一致;--pod-network-cidr:此选项用于指定为 Pod 分配使用的网络地址,它通常应该与要部署使用的网络插件(例如 flannel、calico 等)的默认设定保持一致,10.244.0.0/16是 flannel 默认使用的网络;--service-cidr:用于指定为 Service 分配使用的网络地址,它由 kubernetes 管理,默认即为10.96.0.0/12;--ignore-preflight-errors=Swap仅应该在未禁用 Swap 设备的状态下使用。
初始化方式二¶
kubeadm 也可通过配置文件加载配置,以定制更丰富的部署选项。以下是个符合前述命令设定方式的使用示例。
不过,它明确定义了 kubeProxy 的模式为 ipvs,并支持通过修改 imageRepository 的值修改获取系统镜像时使用的镜像仓库。
1 | apiVersion: kubeadm.k8s.io/v1alpha2 |
将上面的内容保存于配置文件中,例如 kubeadm-config.yaml,而后执行相应的命令:
1 | kubeadm init --config kubeadm-config.yaml --ignore-preflight-errors=Swap |
2、初始化 kubectl¶
kubectl 是 kube-apiserver 的命令行客户端程序,实现了除系统部署之外的几乎全部的管理操作,是 kubernetes 管理员使用最多的命令之一。
kubectl 需经由 API server 认证及授权后方能执行相应的管理操作,kubeadm 部署的集群为其生成了一个具有管理员权限的认证配置文件 /etc/kubernetes/admin.conf,它可由 kubectl 通过默认的 $HOME/.kube/config 的路径进行加载。
当然,用户也可在 kubectl 命令上使用 --kubeconfig 选项指定一个别的位置。
下面复制认证为 Kubernetes 系统管理员的配置文件至目标用户(例如当前用户 root)的家目录下:
1 | mkdir ~/.kube |
而后,即可通过 kubectl 进行客户端命令测试,并借此了解集群组件的当前状态:
1 | kubectl get componentstatus |
一个正常的输出应该类似如下输出结果所示:
1 | NAME STATUS MESSAGE ERROR |
3、添加 flannel 网络附件¶
flannel 的 Github 地址:https://github.com/coreos/flannel
Kubernetes 系统上 Pod 网络的实现依赖于第三方插件进行,这类插件有近数十种之多,较为著名的有 flannel、calico、canal 和 kube-router 等,简单易用的实现是为 CoreOS 提供的 flannel 项目。下面的命令用于在线部署 flannel 至 Kubernetes 系统之上:
1 | kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml |
而后使用如下命令确认其输出结果中 Pod 的状态为 Running,类似如下所示:
1 | kubectl get pods -n kube-system -l app=flannel |
而后使用如下命令确认其输出结果中,所有的 Pod 的状态均为 Running:
1 | kubectl get pods -n kube-system |
4、验正 master 节点已经就绪¶
1 | kubectl get nodes |
上述命令应该会得到类似如下输出:
1 | NAME STATUS ROLES AGE VERSION |
五、添加节点到集群中¶
注意:在 node01 和 node02 上分别完成如下操作
1、禁用 Swap¶
若未禁用 Swap 设备,编辑 kubelet 的配置文件 /etc/sysconfig/kubelet,设置其忽略 Swap 启用的状态错误,内容如下:
1 | KUBELET_EXTRA_ARGS="--fail-swap-on=false" |
2、将 Node 节点加入集群¶
将节点加入第二步中创建的 master 的集群中。
要使用主节点初始化过程中记录的 kubeadm join 命令,并且在未禁用 Swap 设备的情况下,额外附加 --ignore-preflight-errors=Swap 选项。
注意:
添加过程需要访问 Google 的网站下载镜像,但是因为某种不可抗力的原因,访问不稳定,所以最好等到一个节点完全安装好后,再进行下一个节点的安装。
可以在 Master 节点使用以下命令查看是否安装完毕,kubectl get pods -n kube-system。
在确认所有 pod 已经下载好并Running后,再进行下一个节点的添加。
每个人的命令都不一样,在 Node 节点,执行主节点初始化过程中最后的命令,类似如下:
1 | kubeadm join 172.20.0.71:6443 --token gwxgdg.igg5728t1vt8ahhx --discovery-token-ca-cert-hash sha256:9b63cd1530b50da4733d2e7dace9270782211e25ec2e4bbac395e59adc56a26c --ignore-preflight-errors=Swap |
3、验证¶
在每个节点添加完成后,即可通过 kubectl 验正添加结果。下面的命令及其输出是在 node01 和 node02 均添加完成后运行的,其输出结果表明两个 Node 已经准备就绪。
1 | kubectl get nodes |
到此为止,一个 master,并附带有两个 node 的 kubernetes 集群基础设施已经部署完成,用户随后即可测试其核心功能。
例如,下面的命令可将 myapp 镜像以 Pod 的形式编排运行于集群之上,并通过在集群外部进行访问:
1 | kubectl create deployment myapp --image=ikubernetes/myapp:v1 |
而后,使用如下命令了解 Service 对象 myapp 使用的 NodePort,以便于在集群外部进行访问:
1 | kubectl get svc -l app=myapp |
myapp 是一个 web 应用,因此用户可以于集群外部通过 http://NodeIP:31257 这个 URL 访问 myapp 上的应用,例如于集群外通过浏览器访问 http://172.20.0.61:31257。