0%

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

从零开始搭建 k8s 集群环境系列笔记:

搭建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 的安装文件包。其他系统的什么 Ubuntu、OS X、Windows 什么的,就请各显神通了。其实原理也差不多。

下载/克隆源码

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独享(媳妇看视频用掉的不算),容器中 fedora 的 dnf 指令安装源码需要的环境,竟然出其的慢,可以说是下载不下来!
于是乎,决定修改源代码的 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 通过探针的方式来检查容器的健康状态,具体可参考 Kubernetes 之 Pod 详解 Pod 健康检查。

5. cAdvisor资源监控

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

kubeadm

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

kubectl

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

kubernetes-cni

kubernetes-cni 是 Kubernetes 所使用的网络插件。

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