0%

从零开始搭建k8s集群环境(二)——构建Kubernetes安装包

系列目录:

搭建k8s集群必然少不了要安装k8s,在CentOS中,一般我们可以设置yum源安装。但是,本着打破砂锅问到底的精神,源码摆在那里,不自己编译需要的版本怎么行!~

环境说明:

  • Master:VBox虚拟机/Centos_7.5-1804/192.168.56.100
  • Images:VBox虚拟机/Centos_7.5-1804/192.168.56.101
  • Node01:VBox虚拟机/Centos_7.5-1804/192.168.56.102

软件环境说明:

  • docker-ce-17.03.2
  • kubernetes-v1.9.0
  • harbor-v1.4.0

这里使用 Master 做编译机器。

这么没什么好说的,我也是这两天翻遍无数博客找到的。

Github:kubernetes/release

因为我的环境是 CentOS,所以我最终需要 rpm 的安装文件包。其他系统的什么 UbuntuOS XWindows 什么的,就请各显神通了。其实原理也差不多。

下载/克隆源码

git clone https://github.com/kubernetes/release

下载还是克隆敬请随意,我这为了方便编译不同版本的安装包,就用git克隆了下来。

二、编译

1.先决条件

Docker

Docker 使用离线版 docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm 下载地址: https://download.docker.com/linux/centos/7/x86_64/stable/Packages/

wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-selinux-17.03.2.ce-1.el7.centos.x86_64.rpm

# 将安装 Docker 和依赖包
yum install -y docker-ce-*.rpm

启动docker

systemctl enable docker
systemctl restart docker

查看docker版本

$ docker version

Client:
 Version:      17.03.2-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   f5ec1e2
 Built:        Tue Jun 27 02:21:36 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.2-ce
 API version:  1.27 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   f5ec1e2
 Built:        Tue Jun 27 02:21:36 2017
 OS/Arch:      linux/amd64
 Experimental: false

Docker Mirror

编译环境本身需要 fedora:24 的容器。所以,在国内这种环境下,怎么也得加个镜像。 怎么加?加载哪?加谁的?请点击我查看.

2.填坑

镜像下载慢

由于源码中编译所使用的镜像是 fedora:24,在上面阿里云镜像的加持下,顺利的趟过了第一条坑.

软件源慢

但是,楼主坐标成都,电信宽带50M独享(媳妇看视频用掉的不算),容器中 fedoradnf 指令安装源码需要的环境,竟然出其的慢,可以说是下载不下来! 于是乎,决定修改源代码的 Dockerfile 使用 centos 作为容器系统,毕竟这两个系统区别不大。

进入 rpm 编译目录

cd ./release/rpm

编辑 Dockerfile 文件

vim Dockerfile

原始内容

FROM fedora:24
MAINTAINER Devan Goodwin <dgoodwin@redhat.com>

RUN dnf install -y rpm-build rpmdevtools createrepo && dnf clean all

RUN rpmdev-setuptree

USER root
ADD entry.sh /root/
COPY ./ /root/rpmbuild/SPECS
ENTRYPOINT ["/root/entry.sh"]

系统由 FROM fedora:24 换成了 FROM centos:latest 对应的包管理器 dnf 换为了 yum

最终结果为

FROM centos:latest
MAINTAINER Devan Goodwin <dgoodwin@redhat.com>

RUN yum install -y rpm-build rpmdevtools createrepo && yum clean all

RUN rpmdev-setuptree

USER root
ADD entry.sh /root/
COPY ./ /root/rpmbuild/SPECS
ENTRYPOINT ["/root/entry.sh"]

进过测试,楼主这个地方用起来没得问题,容器软件源问题解决.

二进制文件源慢

屋漏偏逢连夜雨,刚把环境问题解决,本以为可以策马奔腾了,没想到又被当头一棒! 这套脚本其实不能叫做源码,实际上它是将 k8s 软件二进制文件和系统"融合"打包的一套脚本,在打包过程中,它要去 https://dl.k8s.io 下载对应版本的二进制文件,包含以下四个文件:

kubeadm
kubectl
kubelet
cni-plugins-amd64-v0.6.0.tgz

楼主这个地方,很奇怪,能下载的时候 5+M/s,不能下载就一点都下载不了,着实很可恶。

于是,为了节约宝贵的时间,我将这几个文件预先下载了下来,然后通过自建 http 服务器提供下载,当然,我们需要修改脚本中的下载地址,在 kubelet.spec 这个文件中: v1.9.0 这个版本目前是在 26 -36 行直接,内容如下:

···
URL: https://kubernetes.io
Source0: https://dl.k8s.io/v%{KUBE_VERSION}/bin/linux/%{ARCH}/kubelet
Source1: kubelet.service
Source2: https://dl.k8s.io/v%{KUBE_VERSION}/bin/linux/%{ARCH}/kubectl
Source3: https://dl.k8s.io/v%{KUBE_VERSION}/bin/linux/%{ARCH}/kubeadm
Source4: 10-kubeadm.conf
%if %{KUBE_SEMVER} < %{semver 1 9 0}
Source5: https://dl.k8s.io/network-plugins/cni-%{ARCH}-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz
%else
Source5: https://dl.k8s.io/network-plugins/cni-plugins-%{ARCH}-v%{CNI_VERSION}.tgz
%endif
···

这里大家按需修改,不排除不修改也能顺利下载.我贴一下我的:

···
URL: https://kubernetes.io
Source0: http://192.168.56.20/v%{KUBE_VERSION}/bin/linux/%{ARCH}/kubelet
Source1: kubelet.service
Source2: http://192.168.56.20/v%{KUBE_VERSION}/bin/linux/%{ARCH}/kubectl
Source3: http://192.168.56.20/v%{KUBE_VERSION}/bin/linux/%{ARCH}/kubeadm
Source4: 10-kubeadm.conf
%if %{KUBE_SEMVER} < %{semver 1 9 0}
Source5: http://192.168.56.20/network-plugins/cni-%{ARCH}-0799f5732f2a11b329d9e3d51b9c8f2e3759f2ff.tar.gz
%else
Source5: http://192.168.56.20/network-plugins/cni-plugins-%{ARCH}-v%{CNI_VERSION}.tgz
%endif
···

我用 nginx 临时运行了一个服务器,创建了对应的目录,放入了对应的文件.搞了半小时,终于不在下载超时了~

CentOS容器内无写权限

这个坑,差点没把我埋掉!MMP! 具体描述一下就是:在脚本源码编译几乎完成的时候,报出目录无法写入;楼主学艺不精,试了好一阵才确定是容器内挂载目录的权限问题,因为最终编译的安装包需要通过挂载目录输出到容器外. 百度后得知原因:在 CentOS7 系统中,由于 SELinux 的控制, Dockerfile 中挂载的主机目录,容器中访问出现 Premission denied 的权限问题.

解决办法有三:

1.在运行容器的时候,给容器加特权,也就是加上 --privileged=true 参数:

如下运行容器则无此问题:

docker run --privileged=true

2.临时关闭 selinux

setenfor 0

3.添加 selinux 规则,改变要挂载的目录的安全性文本

chcon [-R] [-t type] [-u user] [-r role] 文件或者目录

选顷不参数: 
-R  :连同该目录下癿次目录也同时修改; 
-t  :后面接安全性本文的类型字段!例如 httpd_sys_content_t ; 
-u  :后面接身份识别,例如 system_u; 
-r  :后面街觇色,例如 system_r

# 根据格式我们需要更改/data/share/master的安全性文档
chcon -Rt svirt_sandbox_file_t /root/relrase/rpm/output/

我选择第一种方法,所以需要修改 docker-build.sh 这个文件:

#!/bin/sh
set -e

docker build -t kubelet-rpm-builder .
echo "Cleaning output directory..."
sudo rm -rf output/*
mkdir -p output
docker run -ti --rm -v $PWD/output/:/root/rpmbuild/RPMS/ kubelet-rpm-builder $1
sudo chown -R $USER $PWD/output

echo
echo "----------------------------------------"
echo
echo "RPMs written to: "
ls $PWD/output/*/
echo
echo "Yum repodata written to: "
ls $PWD/output/*/repodata/

变更第八行 docker 命令后如下:

#!/bin/sh
set -e

docker build -t kubelet-rpm-builder .
echo "Cleaning output directory..."
sudo rm -rf output/*
mkdir -p output
docker run -ti --rm --privileged=true -v $PWD/output/:/root/rpmbuild/RPMS/ kubelet-rpm-builder $1
sudo chown -R $USER $PWD/output

echo
echo "----------------------------------------"
echo
echo "RPMs written to: "
ls $PWD/output/*/
echo
echo "Yum repodata written to: "
ls $PWD/output/*/repodata/

至此,我所遇到的坑就填完了~!感谢上苍~!

3.安装

编译完成之后,会在 release/rpm/ 文件夹下生成 output/x86_64/ 目录

[root@localhost rpm]# ll output/x86_64/
总用量 51904
-rw-r--r--. 1 root root 17237284 5月  20 00:37 kubeadm-1.9.0-0.x86_64.rpm
-rw-r--r--. 1 root root  9305472 5月  20 00:37 kubectl-1.9.0-0.x86_64.rpm
-rw-r--r--. 1 root root 17588884 5月  20 00:37 kubelet-1.9.0-0.x86_64.rpm
-rw-r--r--. 1 root root  9003712 5月  20 00:37 kubernetes-cni-0.6.0-0.x86_64.rpm
drwxr-xr-x. 2 root root     4096 5月  20 00:37 repodata

由于 kubelet 依赖 socat,所以需要先安装 socat,在安装 rpm 包:

[root@localhost rpm]# yum install socat -y

[root@localhost rpm]# rpm -ivh output/x86_64/*.rpm
准备中...                          ################################# [100%]
正在升级/安装...
   1:kubernetes-cni-0.6.0-0           ################################# [ 25%]
   2:kubelet-1.9.0-0                  ################################# [ 50%]
   3:kubectl-1.9.0-0                  ################################# [ 75%]
   4:kubeadm-1.9.0-0                  ################################# [100%]

三、认识 Kubernetes

研究搞了这么久,总算是功夫不负有心人;是时候来认识认识这几个包了。

kubelet

1. kubelet简介

kubernetes 集群中,每个 Node 节点都会启动 kubelet 进程,用来处理 Master 节点下发到本节点的任务,管理 Pod 和其中的容器。kubelet 会在 API Server 上注册节点信息,定期向 Master 汇报节点资源使用情况,并通过 cAdvisor 监控容器和节点资源。可以把 kubelet 理解成 Server-Agent 架构中的 agent,是 Node 上的 pod 管家。 更多 kubelet 配置参数信息可参考 kubelet –help

2. 节点管理

节点通过设置 kubelet 的启动参数 –register-node,来决定是否向 API Server 注册自己,默认为 true。可以通过 kubelet –help 或者查看 kubernetes 源码 cmd/kubelet/app/server.go 中来查看该参数。

3. Pod管理

kubelet 有几种方式获取自身 Node 上所需要运行的 Pod 清单。但本文只讨论通过 API Server 监听 etcd 目录,同步 Pod 列表的方式。 kubelet 通过 API Server Client 使用 WatchAndList 的方式监听 etcd/registry/nodes/${当前节点名称}/registry/pods 的目录,将获取的信息同步到本地缓存中。 kubelet 监听 etcd,执行对 Pod 的操作,对容器的操作则是通过 Docker Client 执行,例如启动删除容器等。

4. 容器健康检查

Pod 通过探针的方式来检查容器的健康状态,具体可参考 KubernetesPod 详解 Pod 健康检查。

5. cAdvisor资源监控

kubelet 通过 cAdvisor 获取本节点信息及容器的数据。cAdvisor 为谷歌开源的容器资源分析工具,默认集成到 kubernetes 中。 cAdvisor 自动采集 CPU内存文件系统网络使用情况容器中运行的进程,默认端口为 4194。可以通过 Node IP+Port 访问。

kubeadm

kubeadmKubernetes 官方推出的快速部署 Kubernetes 集群工具,其思路是将 Kubernetes 相关服务容器化( Kubernetes 静态 Pod )以简化部署。

kubectl

kubectl 是个客户端工具,可以安装在任意一台 LinuxWindows 或者 Mac 电脑上,只要这个电脑能够连接 master 节点,进而管理整个集群。

kubernetes-cni

kubernetes-cniKubernetes 所使用的网络插件。

ok,结束~!早点睡,为明天的工作做准备!