说了很久的容器计划,现在终于有时间实际操作下了,前期学习有很些概念,虽然有Rancher OS和CoreOS这类的发行版,但Kubernetes集群的安装也不是太麻烦,因此,还是先从最基本的实验下。以下是本人CentOS7.6上安装Kubernetes集群的笔记,持续更新...。

Kubernetes主机环境预设

Kubernete集群的主机生产环境也有多种选择,如下:

  • 方案一: 三台或者五台 Master 节点,分别安装全角色:ETCD , Control Plane ;其他节点为容器计算机节点,分别安装角色: worker;
  • 方案二: 三台节点分别安装角色:ETCD;两台节点分别安装角色:Control Plane;其他节点为容器计算机节点,分别安装角色: worker;

但我现在手上只有一台7代i7的笔记本,虽有16G内存,但这双核四线程真不够看啊,单机和minikube安装先不考虑,等小型实验集群实验好后再逐个实现。我的笔记本是安装的fedora,使用kvm虚拟机虚拟了三个主机每个主机也就1vcpu+1G内存,分别安装一个master节点和两个计算节点。
各个节点需要安装的kubernetes组件如下:

  • 主节点:
    • kube-apiserver
    • kube-controller-manager
    • kube-scheduler
    • kube-proxy
    • pause
    • etcd
    • coredns
  • 从节点:
    • kube-proxy
    • pause
    • flannel(本次实验选定的网络插件)

设置时间同步

如chrony,配置文件/etc/chrony.conf(内网需要配置时间服务器),服务启动使用systemctl命令。建议无论内网和能连接Internet的环境都为集群配置时间同步服务器。

配置DNS或者hosts主机解析

在/etc/hosts文件中配置集群的IP和主机名解析(同时可以减少DNS的解析时延)

关闭防火墙

CentOS7上关闭防火墙

# systemctl stop firewalld.service

# systemctl disable firewalld.service

关闭SELinux

# setenforce 0

同时配置时/etc/selinux/config文件

# vim /etc/selinux/config
...
SELINUX=disable

或者

# sed -i 's@^\(SELINUX=\).*@\1disabled@' /etc/sysconfig/selinux

禁用swap设备

查看

# free -m

关闭临时

# swapoff -a

同时编辑配置文件/etc/fstab进行永久关闭,即注释挂载swap设备的行。或者执行

# echo "vm.swappiness = 0" >> /etc/sysctl.conf

注:本次实验由于资源有限没有关闭,但后续有解决方法(仅限于实验环境)

启用IPVS内和模块

创建内核模块加载脚本于目录/etc/sysconfig/modules下。

vim /etc/sysconfig/modules/ipvs.sh

#!/bin/bash
ipvs_mods_dir="/usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs"
for i in $(ls $ipvs_mods_dir | grep -o "^[^.]*"); do
    /sbin/modinfo -F filename $i &> /dev/null
    if [ $? -eq 0 ]; then
        /sbin/modprobe $i
    fi
done

修改文件权限,并手动加载内核模块:

# chmod +x /etc/sysconfig/modules/ipvs.modules
# bash /etc/sysconfig/modules/ipvs.modules

安装程序包

采用docker作为容器运行

配置运行Docker

  • 安装必要的一些系统工具
# yum install -y yum-utils device-mapper-persistent-data lvm2
  • 添加docker源
# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

可以采用国内的镜像加速服务,参照kubernetes的官方文档,这里使用阿里的镜像在CentOS上的安装作为说明(作此笔记的时候尝试过华为、腾讯和电子科大的kubernetes好像版本没有阿里的新,就暂时先用阿里的来做实验了)。

  • 更新并安装 Docker-CE
# yum makecache fast
# yum -y install docker-ce

此处根据默认是docker源文件的配置安装的是最新稳定版,但很有可能不能通过最新的kubernetes的认证。因此,我们采用下面的方式来选择安装版本,特别是再生产环境中。
首先是查找仓库中的版本:

# yum list docker-ce.x86_64 --showduplicates | sort -r
Loading mirror speeds from cached hostfile
Loaded plugins: branch, fastestmirror, langpacks
...
dockdr-ce.x86_64            18.09.9.ce-1.el7.centos            docker-ce-stable
...
docker-ce.x86_64            17.03.1.ce-1.el7.centos            docker-ce-stable
docker-ce.x86_64            17.03.0.ce-1.el7.centos            docker-ce-stable
Available Packages

然后安装指定版本的Docker-CE: (VERSION 例如上面的 18.09.9.ce.1-1.el7.centos)

# yum -y install docker-ce-18.09.9 docker-ce-cli-18.09.9
  • 开启Docker服务
# systemctl start docker
# systemctl enable docker
  • 其它官方文档设置
    创建目录‘/etc/docker’
    # mkdir /etc/docker

    创建daemon

    # cat > /etc/docker/daemon.json <

创建服务目录(官方文档,还不知道干什么用)

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

修改docker服务文件(/usr/lib/systemd/system/docker.service),docker的iptables的FORWARD默认策略为DROP,可能会影响集群通信,需要修改原有的docker.service文件,在"ExecStart=/usr/bin/docker"之后新增一行:

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

重启Docker服务

# systemctl daemon-reload
# systemctl restart docker

添加配置文件k8s.conf

# vim /etc/sysctl.d/99-kubernetes-cri.conf

net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1

生效99-kubernetes-cri.conf

# sysctl --system

配置运行Kubernets

生成kubernets的仓库配置文件

# cat < /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

安装kubeadm、kubelet、kubectl

# yum install kubeadm kubelet kubectl

(可选)拉取初始化所需组件

在初始化命令之前运行镜像拉取命令获取所需组件,同时观察镜像文件的下载过程。

# kubeadm config images pull

如果没有改仓库则默认从k8s.gcr.io去获取,国内环境时获取不到,因此采用一个变通的方法

# vim k8s-pull-images.sh

#!/bin/bash
REGISTRY=gcr.azk8s.cn/google-containers
# REGISTRY=mirrorgooglecontainers

images=(
  kube-apiserver:v1.15.3
  kube-controller-manager:v1.15.3
  kube-scheduler:v1.15.3
  kube-proxy:v1.15.3
  pause:3.1
  etcd:3.3.10
  coredns:1.3.1
)

for imageName in ${images[@]} ; do
  docker pull ${REGISTRY}/$imageName  
  docker tag ${REGISTRY}/$imageName k8s.gcr.io/$imageName  
  docker rmi ${REGISTRY}/$imageName
done

其中组件包列表可以通过命令"kubeadm config images list"获取。

# chmod +x k8s-pull-images.sh
# ./k8s-pull-images.sh

上述脚本保存执行后可以通过"docker image list"查看结果。

kubeadm初始化master节点

初始化命令‘kubeadm’可以使用参数传递和yaml配置文件,测试实验推荐第一种,生产部署推荐第二种。

命令行参数进行初始化

# kubeadm init --kubernetes-version="1.15.3" --pod-network-cidr="10.244.0.0/16"  --service-cidr="10.96.0.0/12" --ignore-preflight-errors=Swap --ignore-preflight-errors=NumCPU --image-reporitory "gcr.azk8s.cn" --dry-run

其中

  • --kubernete-version="1.15.3"指定了kubernete的具体版本,默认的“stable-1”,这里是1.15.0,不符合规定需要修改成当前的版本,此处时1.15.3(查询命令"rpm -qa|grep kubeadm")。
  • --pod-network-cidr="10.244.0.0/16"是自定义的Pod的网络,通常与要部署的网络插件(如:flannel和calico)保持一致,此处使用的时flannel,flannel的默认地址为:10.244.0.0/16,calico的默认地址为:192.168.0.0/16。
  • --ignore-preflight-errors=,这里有两项一个是Swap,一个是NumCPU,他们分别忽略了swap不为0的报错和CPU没有大于2的报错。因为这里我用的是虚拟机,只有1G的内存,因此没有关闭swap;同时虚拟机之分配了一个vCPU。若未禁用swap,则需要编辑kubelet的配置文件/etc/sysconfig/kubelet,忽略swap启用状态错误。
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
  • --server-cidr指定service分配的网络地址,由kubernete管理,默认地址为10.96.0.0/12。
  • --image-reporitory指定组件仓库地址代替默认的"k8s.gcr.io",比如此处国内的gcr.azk8s.cn。
  • --dry-run 只是试运行看有没有什么错误,并没有实际初始化。

最后显示初始化结果

...
Your Kubernetes control-plane has initialized successfully!

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/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.122.10:6443 --token kt9uzn.793zkkepgvup3jg8 \
    --discovery-token-ca-cert-hash sha256:1b00c8c653c5573ff89c134bd1e62a54f3640813b0e26b79f387fddb402b0b48

接下来按照上述初始化结果的提示,创建文件夹(此处用的时root用户)

# mkdir -p ~/.kube
# cp /etc/kubernetes/admin.conf ~/.kube/config

然后安装网络插件,语法:"kubectl apply -f [podnetwork].yaml",此处我们使用的flannel(由coreos研发)。在github的页面上有具体的安装说明,地址https://github.com/coreos/flannel。

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

而后可以使用命令"kubectl get pods -n kube-system"进行查看。

注:

  1. 如果初始化有问题或者要回退使用下面的命令进行重置

    # kubeadm reset
  2. kubeadm init的命令执行过程中有下载,可以使用上面的kubeadm config image pull先把需要的组件包先行下载。

  3. kubeadm初始化时部分告警报错说明
  • kubernete认可的docker版本问题
[WARNING SystemVerification]: this docker version is not on the list of validated version: 19.01.1. Latest validated version: 18.06

以上版本根据自身环境的报告版本有所不同,可以参看kubernetes在git仓库中的changelog文件来确定支持的docker本版,然后根据命令

# yum list docker-ce.x86_64 --showduplicates | sort -r

获取版本列表,然后选取特定的版本进行安装

sudo yum -y install docker-ce-[VERSION]
  • kubelet没有设置自启动
[WARNING Service-Kubelet]: kubelet service is not enabled, please run 'systemctl enable kubelet.service'

解决:执行自启动命令'systemctl enable kubelet.service'

报错说明

  • 没有禁用swap:
[ERROR Swap]: running with swap on is not enabled, please disable swap
[preflight] If you know what you are doing, you can make a check non-fatal with '--ignore-preflight-errors=...'

解决:可以在kubeadm的命令末尾加上参数'--ignore-preflight-errors=Swap'。

通过配置文件进行初始化

通过命令查看默认配置

# kubeadm config print init-defaults

可以调整kubeProxy的模式为ipvs

kubeProxy:
  config:
    mode: "ipvs"
    ipvs:
      ExcludeCIDRs: null
        minSyncPeriod: 0s
        scheduler: ""
        syncPeriod: 30s
...

同时可以修改imageRepository更改获取镜像时使用的仓库

初始化计算节点

计算结点的初始化和主节点类似,执行相同的命令,在安装完kubeadm和kubelet后,设置kubelet服务自启动"systemctl enable kubelet",然后执行主节点初始化后的的提示命令加入机群

# kubeadm join 192.168.122.10:6443 --token i75tol.nbptvcjp8x8yx2lo \
    --discovery-token-ca-cert-hash sha256:eeb70912425f575b47d9b0a2830feb18b7d1ef2807bf454656b2903f04cc472c

如果时测试的虚拟机请注意错误和告警提示,如swap禁用问题,需要在上面的命令后加上"--ignore-preflight-errors=Swap"。成功执行后结果会有如下的类似显示:

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.

加入的过程可能需要点时间,因为加入的节点需要从主节点中拉取所需要的镜像,使用命令"docker image list"可以查看已有组件。

在获取kubernete组件时可以直接使用已下载打包的tar文件直接加载
语法为

docker save -o  

在注节点上查看kubernetes的docker镜像命令:docker image list
在主节点上打包计算节点需要的组件

# docker save -o /home/myk8s-1.15.3.tar docker save -o myk8s-node-1.15.3.tar k8s.gcr.io/pause k8s.gcr.io/kube-proxy quay.io/coreos/flannel

拷贝到计算结点,加载镜像

docker load -i 

然后再执行加入集群的命令。另外,还有docker export/import

  • docker export 导出容器为压缩文件,命令格式如下:
    # docker export -o  

    类似于docker save,指定要输出的文件路径和文件名,后面跟上要导出的容器的名称或者id。

  • docker import 把导出的文件系统导入为镜像,命令格式如下:
    # docker import  

.kube下文件admin.conf才能执行kubectl命令