转载请注明出处:kubernetes—CentOS7安装kubernetes1.11.2图文完整版
架构规划
k8s至少需要一个master和一个node才能组成一个可用集群。
本章我们搭建一个master节点和三个node节点。
我们在生产环境中使用时k8s时可以适当增加节点。
我们有三台服务器,ip和身份规划如下:
192.168.11.90 master node
192.168.11.91 node
192.168.11.92 node
192.168.11.90即作master节点又作node节点。
三台服务器都是CentOS7系统。
注意:Kubernetes 几乎所有的安装组件和 Docker 镜像都放在 goolge 自己的网站上,这对国内的同学可能是个不小的障碍。建议是:网络障碍都必须想办法克服,不然连 Kubernetes 的门都进不了。
设置主机名
分别使用hostname命令把主机名称设置为k8s,k8s1,k8s2
hostname k8s
hostname k8s1
hostname k8s2
- 1
- 2
- 3
然后编辑对应关系,使用命令
vi /etc/hosts
- 1
输入如下:
192.168.11.90 k8s
192.168.11.91 k8s1
192.168.11.92 k8s2
- 1
- 2
- 3
安装方式选择
目前有三种安装方式
下面给出两种安装方式:
第一种是yum安装
配置yum源后,使用yum安装,好处是简单,坏处也很明显,需要google更新yum源才能获得最新版本的软件,而所有软件的依赖又不能自己指定,尤其是你的操作系统版本如果低的话,使用yum源安装的kubernetes的版本也会受到限制。
第一种是二进制安装
使用二进制文件安装,好处是可以安装任意版本的kubernetes,坏处是配置比较复杂。
第三种是kubeadm安装
kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,kubeadm会对集群配置方面的一些实践做调整,通过实验kubeadm可以学习到Kubernetes官方在集群配置上一些新的最佳实践。
1.4版本对于Linux主要发行版本Ubuntu Xenial和Red Hat centos7的用户,可以使用熟悉的apt-get和yum来直接安装Kubernetes。再比如,1.4版本引入了kubeadm命令,将集群启动简化为两条命令,不需要再使用复杂的kube-up脚本。
Kubernetes的官方文档更新的速度太快了,我们注意到在Kubernetes 1.9的文档Using kubeadm to Create a Cluster中已经给出了目前1.9的kubeadm的主要特性已经处于beta状态了,在2018年将进入GA状态,说明kubeadm离可以在生产环境中使用的距离越来越近了。
我们选择使用第三种方式kubeadm安装。
文末转载其他文章的CentOS7第一第二种安装方式以供参考。
版本选择
根据系统和内核的版本,适合安装的版本是不一样的,我们必须先收集好相关对应的版本数据,目前的版本支持哪些版本的docker和k8s,再开始安装,才能事半功倍,否则会出现很多问题。
推荐几个匹配的版本如下:
centos7系统环境
Centos 7.2.1511
docker 1.12.6
etcd 3.1.5
kubernetes 1.6.0
flannel 0.7.0-1
或者
CentOS 7.4
docker 17.03.2
kubernetes 1.9.0
centos6系统环境
centos6
docker-1.7
k8s-1.2
在centos6 + docker-1.7 + k8s-1.2 是能用起来,安装了dashboard、nexus2、harbor,但是对于一些新的东西不能用,并且k8s官网文档不分版本并且没讲明白docker兼容的版本(至少官网文档),感觉人家就是行到自己这里就不行,各种折腾然后到后面是版本问题。docker和k8s在容器大热的当前,版本更新太快了,docker都到1.17了。综上,如果在centos6上面玩玩了解k8s的概况还是好的,但是真的生产环境要用还是升级centos7或者使用ubuntu吧。
更多相关情况
k8s在Centos6部署实践
因为centOS6 在生产环境中意义不大,使用起来版本较老,问题也很多,所以我们记录在centOS7中安装k8s的步骤。版本选择如下:
CentOS 7.4
docker 17.03.2
kubernetes 1.9.0
使用kubeadm安装Kubernetes
注意 以下命令,非root用户需要sudo权限带sudo 执行相关命令。
root用户去掉sudo执行。
关闭防火墙
如果各个主机启用了防火墙,需要开放Kubernetes各个组件所需要的端口,可以查看Installing kubeadm中的”Check required ports”一节。 这里简单起见在各节点禁用防火墙:
centOS 7.0版本
sudo systemctl stop firewalld.service #停止firewall
sudo systemctl disable firewalld.service #禁止firewall开机启动
sudo firewall-cmd --state #查看防火墙状态
- 1
- 2
- 3
禁用SELINUX
sudo setenforce 0
sudo vi /etc/selinux/config
#SELINUX修改为disabled
SELINUX=disabled
- 1
- 2
- 3
- 4
创建/etc/sysctl.d/k8s.conf文件
sudo vi /etc/sysctl.d/k8s.conf
- 1
添加如下内容:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
- 1
- 2
使修改生效,执行
sudo sysctl -p /etc/sysctl.d/k8s.conf
- 1
可能遇到问题—is an unknown key
报错
error: "net.bridge.bridge-nf-call-ip6tables" is an unknown key
error: "net.bridge.bridge-nf-call-iptables" is an unknown key
- 1
- 2
解决方法
sudo modprobe bridge
sudo lsmod |grep bridge
sudo sysctl -p /etc/sysctl.d/k8s.conf
- 1
- 2
- 3
可能遇到问题–sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: 没有那个文件或目录
报错
[root@localhost ~]# sysctl -p /etc/sysctl.d/k8s.conf
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: 没有那个文件或目录
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: 没有那个文件或目录
- 1
- 2
- 3
解决方法
modprobe br_netfilter
ls /proc/sys/net/bridge
sudo sysctl -p /etc/sysctl.d/k8s.conf
- 1
- 2
- 3
转载请注明出处:kubernetes—CentOS7安装kubernetes1.11.2图文完整版
安装Docker
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
- 1
以及
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
- 1
- 2
- 3
查看当前的Docker版本:
使用命令
sudo yum list docker-ce.x86_64 --showduplicates |sort -r
- 1
输出如下:
[zzq@localhost ~]$ sudo yum list docker-ce.x86_64 --showduplicates |sort -r
* updates: mirrors.aliyun.com
Loading mirror speeds from cached hostfile
Loaded plugins: fastestmirror, priorities
* extras: mirrors.aliyun.com
* elrepo: mirrors.tuna.tsinghua.edu.cn
docker-ce.x86_64 18.03.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 18.03.0.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.12.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.12.0.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.09.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.09.0.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.06.2.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.06.1.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.06.0.ce-1.el7.centos docker-ce-stable
docker-ce.x86_64 17.03.2.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
* base: mirrors.aliyun.com
Available Packages
[zzq@localhost ~]$
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
Kubernetes 1.8已经针对Docker的1.11.2, 1.12.6, 1.13.1和17.03等版本做了验证。 因此我们这里在各节点安装docker的17.03.2版本。
使用命令如下:
sudo yum makecache fast
- 1
以及
sudo yum install -y --setopt=obsoletes=0 \
docker-ce-17.03.2.ce-1.el7.centos \
docker-ce-selinux-17.03.2.ce-1.el7.centos
- 1
- 2
- 3
可能遇到的问题
获取 GPG 密钥失败:[Errno 12] Timeout on https://download.docker.com/linux/centos/gpg: (28, 'Operation timed out after 30002 milliseconds with 0 out of 0 bytes received')
- 1
解决方法
一般超时原因都是网络问题,需要检查网络以及能够直接访问到这个资源比如使用命令:
curl -l https://download.docker.com/linux/centos/gpg
- 1
启动和停止docker
centOS7
sudo systemctl start docker
- 1
centOS6
sudo service docker start
- 1
Docker从1.13版本开始调整了默认的防火墙规则,禁用了iptables filter表中FOWARD链,这样会引起Kubernetes集群中跨Node的Pod无法通信,在各个Docker节点执行下面的命令:
sudo iptables -P FORWARD ACCEPT
- 1
同时在docker的systemd unit文件中以ExecStartPost加入允许访问的代码,使用命令如下:
# 为docker服务创建一个systemd插件目录
mkdir -p /etc/systemd/system/docker.service.d
# 创建一个/etc/systemd/system/docker.service.d/port.conf配置文件
vi /etc/systemd/system/docker.service.d/port.conf
- 1
- 2
- 3
- 4
输入以下内容,保存退出:
ExecStartPost=/usr/sbin/iptables -P FORWARD ACCEPT
- 1
重启docker服务
systemctl daemon-reload
systemctl restart docker
- 1
- 2
安装kubeadm和kubelet
下面在各节点安装kubeadm和kubelet,编辑资源库
vi /etc/yum.repos.d/kubernetes.repo
- 1
输入如下内容:
[kubernetes]
name=Kubernetes
baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg
https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
使用命令测试地址是否可用
curl https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
- 1
如果不可用需要科学上网。
可以购买香港或者美国的服务器参考这两篇文章:
搭建shadowsocks
linux使用shadowsocks
如果能正常访问继续安装,使用命令如下:
yum makecache fast
yum install -y kubelet kubeadm kubectl
- 1
- 2
安装完成后输出如下:
已安装:
kubeadm.x86_64 0:1.11.2-0 kubectl.x86_64 0:1.11.2-0 kubelet.x86_64 0:1.11.2-0
作为依赖被安装:
cri-tools.x86_64 0:1.11.0-0 kubernetes-cni.x86_64 0:0.6.0-0 socat.x86_64 0:1.7.3.2-2.el7
- 1
- 2
- 3
- 4
- 5
安装结果可以看出安装的依赖和版本。
如果我们要手动安装,也可以参考相应的依赖版本。
调整启动方式
kubelet的启动环境变量要与docker的cgroup-driver驱动一样。
查看docker的cgroup-driver驱动
使用命令
docker info
或者
docker info | grep -i cgroup
- 1
- 2
- 3
输出如下:
Cgroup Driver: cgroupfs
- 1
可以看出docker 17.03使用的Cgroup Driver为cgroupfs。
Kubernetes文档中kubelet的启动参数:
--cgroup-driver string Driver that the kubelet uses to manipulate cgroups on the host.
Possible values: 'cgroupfs', 'systemd' (default "cgroupfs")
- 1
- 2
默认值为cgroupfs,yum安装kubelet,kubeadm时生成10-kubeadm.conf文件中可能将这个参数值改成了systemd。
查看kubelet的配置文件,其中包含如下内容:
使用命令
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
或者
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf|grep "cgroup-driver"
- 1
- 2
- 3
1.11.2版本的封装在/var/lib/kubelet/kubeadm-flags.env文件中
使用命令
cat /var/lib/kubelet/kubeadm-flags.env|grep "cgroup-driver"
- 1
如果没找到则是默认的cgroupfs,不需要修改。
如果输出如下则需要修改成一致的方式,即可以修改10-kubeadm.conf中的也可以修改docker的。
KUBELET_CGROUP_ARGS=--cgroup-driver=systemd
- 1
我们这里修改各节点docker的cgroup driver使其和kubelet一致
即修改或创建/etc/docker/daemon.json
使用命令
vi /etc/docker/daemon.json
- 1
加入下面的内容:
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
- 1
- 2
- 3
重启docker:
systemctl restart docker
systemctl status docker
- 1
- 2
处理swap
Kubernetes 1.8开始要求关闭系统的Swap,如果不关闭,默认配置下kubelet将无法启动。
可以通过kubelet的启动参数–fail-swap-on=false更改这个限制。
方式一关闭swap
关闭系统的Swap方法如下:
swapoff -a
- 1
同时还需要修改/etc/fstab文件,注释掉 SWAP 的自动挂载,防止机子重启后swap启用。
使用命令
vi /etc/fstab
- 1
输出如下:
#
# /etc/fstab
# Created by anaconda on Tue Jun 19 06:52:02 2018
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=2d32a0e0-9bda-4a68-9abf-6a827a517177 /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
注释swap这一行后保存退出
#/dev/mapper/centos-swap swap swap defaults 0 0
- 1
确认swap已经关闭,使用命令
free -m
- 1
swap输出为0则说明已经关闭,如下:
[root@localhost ~]# free -m
total used free shared buff/cache available
Mem: 976 115 283 6 577 661
Swap: 0 0 0
- 1
- 2
- 3
- 4
k8s的swappiness参数调整,修改配置文件
vi /etc/sysctl.d/k8s.conf
- 1
添加下面一行:
vm.swappiness=0
- 1
执行
sysctl -p /etc/sysctl.d/k8s.conf
- 1
使修改生效。
方式二去掉swap的限制
因为主机上还运行其他服务,关闭swap可能会对其他服务产生影响,则修改kubelet的启动参数去掉这个限制。
修改/etc/systemd/system/kubelet.service.d/10-kubeadm.conf
使用命令
vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
- 1
加入内容:
Environment="KUBELET_EXTRA_ARGS=--fail-swap-on=false"
systemctl daemon-reload
- 1
- 2
启动kubelet服务
在各节点开机启动kubelet服务
使用命令
systemctl enable kubelet.service
systemctl start kubelet.service
- 1
- 2
准备镜像
Kubernetes安装过程中一个很大的问题,相关组件的镜像都是托管在Google Container Registry上的。国内的镜像加速一般针对的是Dockerhub上的镜像。所以国内的服务器是没法直接安装GCR上的镜像的。
注意,这里即使翻墙之后,在执行初始化时仍然会报错
所有最好的解决方法是 在可访问gcr.io/google-containers的国外节点(一般在aws或者全局访问外网的节点)中,把gcr.io的镜像拉到可访问的镜像仓库中,例如Docker Hub或者阿里云等。
设置全局代理后浏览器访问 gcr.io/google-containers 显示如下:
新建仓库
我们这里使用阿里云的镜像仓库作为演示。
阿里云镜像仓库需要注册登录访问地址如下:
https://cr.console.aliyun.com/cn-hangzhou/repositories
根据如下步骤:
创建镜像仓库
命名-公开
本地仓库
创建完成后点击管理
这样我们就拿到了这个镜像仓库的公网地址
registry.cn-qingdao.aliyuncs.com/joe-k8s/k8s
- 1
登录命令
docker login --username=xxx registry.cn-qingdao.aliyuncs.com
- 1
登录密码在 首页设置
首先登录 仓库
运行命令
登录命令
docker login --username=xxx registry.cn-qingdao.aliyuncs.com
- 1
输入密码。
登录成功输出如下:
[root@k8s ~]# docker login --username=xxx registry.cn-qingdao.aliyuncs.com
Password:
Login Succeeded
- 1
- 2
- 3
获取版本号
K8s每个版本需要的镜像版本号在kubeadm Setup Tool Reference Guide这个文档的的Running kubeadm without an internet connection一节里有写。所以可以根据安装的实际版本来调整这个脚本的参数。注意把上面的镜像地址换成自己的。k8s是你创建的一个namespace,而不是仓库名。
如图可以看到 1.11版本的k8s可以使用命令获取需要的镜像版本如下:
kubeadm config images list
- 1
输出如下:
k8s.gcr.io/kube-apiserver-amd64:v1.11.2
k8s.gcr.io/kube-controller-manager-amd64:v1.11.2
k8s.gcr.io/kube-scheduler-amd64:v1.11.2
k8s.gcr.io/kube-proxy-amd64:v1.11.2
k8s.gcr.io/pause:3.1
k8s.gcr.io/etcd-amd64:3.2.18
k8s.gcr.io/coredns:1.1.3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
准备镜像仓库
方式一有国外服务器节点编写脚本获取推送镜像
在国外的服务器节点创建脚本
vi push.sh
- 1
根据我们的经新仓库链接和需要的镜像版本号调整脚本如下:
#!/bin/bash
set -o errexit
set -o nounset
set -o pipefail
KUBE_VERSION=v1.11.2
KUBE_PAUSE_VERSION=3.1
ETCD_VERSION=3.2.18
DNS_VERSION=1.1.3
GCR_URL=gcr.io/google-containers
ALIYUN_URL=registry.cn-qingdao.aliyuncs.com/joe-k8s/k8s
images=(kube-proxy-amd64:${KUBE_VERSION}
kube-scheduler-amd64:${KUBE_VERSION}
kube-controller-manager-amd64:${KUBE_VERSION}
kube-apiserver-amd64:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd-amd64:${ETCD_VERSION}
coredns:${DNS_VERSION})
for imageName in ${images[@]}
do
docker pull $GCR_URL/$imageName
docker tag $GCR_URL/$imageName $ALIYUN_URL/$imageName
docker push $ALIYUN_URL/$imageName
docker rmi $ALIYUN_URL/$imageName
done
- 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
运行push.sh
sh push.sh
- 1
成功获取和push之后我们的镜像仓库registry.cn-qingdao.aliyuncs.com/joe-k8s/k8s中就有了相关的包。
方式二使用别人在国内做好的镜像仓库
如果没有国外的服务器节点,那我们就不能自由的定制需要的版本号镜像了。只能去找找别人已经做好的镜像仓库中有哪些版本,是否有在更新。
目前做的比较好的 持续更新的 k8s镜像仓库推荐 安家的。
Google Container Registry(gcr.io) 中国可用镜像(长期维护)
安家的github
镜像目录
我们在镜像目录中可以看到 v1.11.2版本的镜像也是有了的,可以使用。
这里的镜像目录https://hub.docker.com/u/anjia0532/与我们自己准备的镜像仓库registry.cn-qingdao.aliyuncs.com/joe-k8s/k8s 是同等的作用,下面会用到。
获取镜像
在master节点创建获取的脚本
vi pull.sh
- 1
根据自己的镜像仓库获取地址调整脚本,如下:
#!/bin/bash
KUBE_VERSION=v1.11.2
KUBE_PAUSE_VERSION=3.1
ETCD_VERSION=3.2.18
DNS_VERSION=1.1.3
username=registry.cn-qingdao.aliyuncs.com/joe-k8s/k8s
images=(kube-proxy-amd64:${KUBE_VERSION}
kube-scheduler-amd64:${KUBE_VERSION}
kube-controller-manager-amd64:${KUBE_VERSION}
kube-apiserver-amd64:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd-amd64:${ETCD_VERSION}
coredns:${DNS_VERSION}
)
for image in ${images[@]}
do
docker pull ${username}/${image}
docker tag ${username}/${image} k8s.gcr.io/${image}
#docker tag ${username}/${image} gcr.io/google_containers/${image}
docker rmi ${username}/${image}
done
unset ARCH version images username
- 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
运行
sh pull.sh
- 1
注意,安家的脚本因为修改过命名使用的pull.sh脚本如下:
#!/bin/bash
KUBE_VERSION=v1.11.2
KUBE_PAUSE_VERSION=3.1
ETCD_VERSION=3.2.18
DNS_VERSION=1.1.3
username=anjia0532
images=(google-containers.kube-proxy-amd64:${KUBE_VERSION}
google-containers.kube-scheduler-amd64:${KUBE_VERSION}
google-containers.kube-controller-manager-amd64:${KUBE_VERSION}
google-containers.kube-apiserver-amd64:${KUBE_VERSION}
pause:${KUBE_PAUSE_VERSION}
etcd-amd64:${ETCD_VERSION}
coredns:${DNS_VERSION}
)
for image in ${images[@]}
do
docker pull ${username}/${image}
docker tag ${username}/${image} k8s.gcr.io/${image}
#docker tag ${username}/${image} gcr.io/google_containers/${image}
docker rmi ${username}/${image}
done
unset ARCH version images username
- 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
检查镜像
使用命令
docker images
- 1
发现已经有了需要的镜像
[root@k8s ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
k8s.gcr.io/google-containers.kube-apiserver-amd64 v1.11.2 821507941e9c 6 days ago 187 MB
k8s.gcr.io/google-containers.kube-proxy-amd64 v1.11.2 46a3cd725628 6 days ago 97.8 MB
k8s.gcr.io/google-containers.kube-controller-manager-amd64 v1.11.2 38521457c799 6 days ago 155 MB
k8s.gcr.io/google-containers.kube-scheduler-amd64 v1.11.2 37a1403e6c1a 6 days ago 56.8 MB
k8s.gcr.io/coredns 1.1.3 b3b94275d97c 2 months ago 45.6 MB
k8s.gcr.io/etcd-amd64 3.2.18 b8df3b177be2 4 months ago 219 MB
k8s.gcr.io/pause 3.1 da86e6ba6ca1 7 months ago 742 kB
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
注意 这里的前缀需要与kubeadm config images list时输出的前缀对应,否则init时仍然会识别不到去下载。
我们这里是k8s.gcr.io所以 脚本中pull 时重命名使用的是
docker tag ${username}/${image} k8s.gcr.io/${image}
- 1
如果使用的是anjia0532的版本则还需要调整一遍命名,使用命令如下:
docker tag k8s.gcr.io/google-containers.kube-apiserver-amd64:v1.11.2 k8s.gcr.io/kube-apiserver-amd64:v1.11.2
docker tag k8s.gcr.io/google-containers.kube-controller-manager-amd64:v1.11.2 k8s.gcr.io/kube-controller-manager-amd64:v1.11.2
docker tag k8s.gcr.io/google-containers.kube-scheduler-amd64:v1.11.2 k8s.gcr.io/kube-scheduler-amd64:v1.11.2
docker tag k8s.gcr.io/google-containers.kube-proxy-amd64:v1.11.2 k8s.gcr.io/kube-proxy-amd64:v1.11.2
- 1
- 2
- 3
- 4
准备好的镜像如下,与kubeadm config images list时输出的镜像名称版本一致。
[root@k8s ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
k8s.gcr.io/kube-controller-manager-amd64 v1.11.2 38521457c799 6 days ago 155 MB
k8s.gcr.io/kube-apiserver-amd64 v1.11.2 821507941e9c 6 days ago 187 MB
k8s.gcr.io/kube-proxy-amd64 v1.11.2 46a3cd725628 6 days ago 97.8 MB
k8s.gcr.io/kube-scheduler-amd64 v1.11.2 37a1403e6c1a 6 days ago 56.8 MB
k8s.gcr.io/coredns 1.1.3 b3b94275d97c 2 months ago 45.6 MB
k8s.gcr.io/etcd-amd64 3.2.18 b8df3b177be2 4 months ago 219 MB
k8s.gcr.io/pause 3.1 da86e6ba6ca1 7 months ago 742 kB
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
使用kubeadm init初始化集群 (只在主节点执行)
初始化前确认 kubelet启动和 cgroup-driver等方式是否对应。
接下来使用kubeadm初始化集群,选择k8s作为Master Node
确保没有设置http_proxy和https_proxy代理
在k8s上执行下面的命令:
kubeadm init --kubernetes-version=v1.11.2 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.11.90 --token-ttl 0
- 1
–kubernetes-version根据上面安装成功时的提示:kubectl.x86_64 0:1.11.2-0对应版本。
因为我们选择flannel作为Pod网络插件,所以上面的命令指定–pod-network-cidr=10.244.0.0/16。
对于某些网络解决方案,Kubernetes master 也可以为每个节点分配网络范围(CIDR),这包括一些云提供商和 flannel。通过 –pod-network-cidr 参数指定的子网范围将被分解并发送给每个 node。这个范围应该使用最小的 /16,以让 controller-manager 能够给集群中的每个 node 分配 /24 的子网。如果我们是通过 这个 manifest 文件来使用 flannel,那么您应该使用 –pod-network-cidr=10.244.0.0/16。大部分基于 CNI 的网络解决方案都不需要这个参数。
–apiserver-advertise-address是apiserver的通信地址,一般使用master的ip地址。
通过kubeadm初始化后,都会提供节点加入k8s集群的token。默认token的有效期为24小时,当过期之后,该token就不可用了,需要重新生成token,会比较麻烦,这里–token-ttl设置为0表示永不过期。
token过期后重新创建token的方法看文末。
可能遇到的问题-卡在preflight/images
init过程中kubernetes会自动从google服务器中下载相关的docker镜像
kubeadm init过程首先会检查代理服务器,确定跟 kube-apiserver 的 https 连接方式,如果有代理设置,会提出警告。
如果一直卡在preflight/images
[preflight/images] Pulling images required for setting up a Kubernetes cluster
[preflight/images] This might take a minute or two, depending on the speed of your internet connection
[preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull'
- 1
- 2
- 3
请查看上一小节,先准备相关镜像。
可能遇到的问题-uses proxy
如果报错
[WARNING HTTPProxy]: Connection to "https://192.168.11.90" uses proxy "http://127.0.0.1:8118". If that is not intended, adjust your proxy settings
[WARNING HTTPProxyCIDR]: connection to "10.96.0.0/12" uses proxy "http://127.0.0.1:8118". This may lead to malfunctional cluster setup. Make sure that Pod and Services IP ranges specified correctly as exceptions in proxy configuration
[WARNING HTTPProxyCIDR]: connection to "10.244.0.0/16" uses proxy "http://127.0.0.1:8118". This may lead to malfunctional cluster setup. Make sure that Pod and Services IP ranges specified correctly as exceptions in proxy configuration
- 1
- 2
- 3
则设置no_proxy
使用命令
vi /etc/profile
- 1
在最后添加
export no_proxy='anjia0532,127.0.0.1,192.168.11.90,k8s.gcr.io,10.96.0.0/12,10.244.0.0/16'
- 1
使用命令让配置生效
source /etc/profile
- 1
更多init的错误可以新开一个控制台使用命令跟踪:
journalctl -f -u kubelet.service
- 1
可以查看具体的卡住原因。
可能遇到的问题-failed to read kubelet config file “/var/lib/kubelet/config.yaml”
8月 14 20:44:42 k8s systemd[1]: kubelet.service holdoff time over, scheduling restart.
8月 14 20:44:42 k8s systemd[1]: Started kubelet: The Kubernetes Node Agent.
8月 14 20:44:42 k8s systemd[1]: Starting kubelet: The Kubernetes Node Agent...
8月 14 20:44:42 k8s kubelet[5471]: F0814 20:44:42.477878 5471 server.go:190] failed to load Kubelet config file /var/lib/kubelet/config.yaml, error failed to read kubelet config file "/var/lib/kubelet/config.yaml", error: open /var/lib/kubelet/config.yaml: no such file or directory
- 1
- 2
- 3
- 4
原因
关键文件缺失,多发生于没有做 kubeadm init就运行了systemctl start kubelet。
解决方法
先成功运行kubeadm init。
可能遇到的问题–cni config uninitialized
KubeletNotReady runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized
- 1
原因
因为kubelet配置了network-plugin=cni,但是还没安装,所以状态会是NotReady,不想看这个报错或者不需要网络,就可以修改kubelet配置文件,去掉network-plugin=cni 就可以了。
解决方法
vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
- 1
删除最后一行里的$KUBELET_NETWORK_ARGS
1.11.2版本的封装在/var/lib/kubelet/kubeadm-flags.env文件中
使用命令
[root@k8s ~]# cat /var/lib/kubelet/kubeadm-flags.env
KUBELET_KUBEADM_ARGS=--cgroup-driver=systemd --cni-bin-dir=/opt/cni/bin --cni-conf-dir=/etc/cni/net.d --network-plugin=cni
- 1
- 2
重启kubelet
systemctl enable kubelet && systemctl start kubelet
- 1
重新初始化
kubeadm reset
kubeadm init --kubernetes-version=v1.11.2 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.11.90 --token-ttl 0
- 1
- 2
正确初始化输出如下:
[root@k8s ~]# kubeadm init --kubernetes-version=v1.11.2 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.11.90 --token-ttl 0
[init] using Kubernetes version: v1.11.2
[preflight] running pre-flight checks
I0815 16:24:34.651252 21183 kernel_validator.go:81] Validating kernel version
I0815 16:24:34.651356 21183 kernel_validator.go:96] Validating kernel config
[preflight/images] Pulling images required for setting up a Kubernetes cluster
[preflight/images] This might take a minute or two, depending on the speed of your internet connection
[preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull'
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[preflight] Activating the kubelet service
[certificates] Generated ca certificate and key.
[certificates] Generated apiserver certificate and key.
[certificates] apiserver serving cert is signed for DNS names [k8s kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.11.90]
[certificates] Generated apiserver-kubelet-client certificate and key.
[certificates] Generated sa key and public key.
[certificates] Generated front-proxy-ca certificate and key.
[certificates] Generated front-proxy-client certificate and key.
[certificates] Generated etcd/ca certificate and key.
[certificates] Generated etcd/server certificate and key.
[certificates] etcd/server serving cert is signed for DNS names [k8s localhost] and IPs [127.0.0.1 ::1]
[certificates] Generated etcd/peer certificate and key.
[certificates] etcd/peer serving cert is signed for DNS names [k8s localhost] and IPs [192.168.11.90 127.0.0.1 ::1]
[certificates] Generated etcd/healthcheck-client certificate and key.
[certificates] Generated apiserver-etcd-client certificate and key.
[certificates] valid certificates and keys now exist in "/etc/kubernetes/pki"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
[kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
[controlplane] wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"
[controlplane] wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
[controlplane] wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"
[etcd] Wrote Static Pod manifest for a local etcd instance to "/etc/kubernetes/manifests/etcd.yaml"
[init] waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests"
[init] this might take a minute or longer if the control plane images have to be pulled
[apiclient] All control plane components are healthy after 40.004083 seconds
[uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
[kubelet] Creating a ConfigMap "kubelet-config-1.11" in namespace kube-system with the configuration for the kubelets in the cluster
[markmaster] Marking the node k8s as master by adding the label "node-role.kubernetes.io/master=''"
[markmaster] Marking the node k8s as master by adding the taints [node-role.kubernetes.io/master:NoSchedule]
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s" as an annotation
[bootstraptoken] using token: hu2clf.898he8fnu64w3fur
[bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
[bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
[bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
[bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes master 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/
You can now join any number of machines by running the following on each node
as root:
kubeadm join 192.168.11.90:6443 --token hu2clf.898he8fnu64w3fur --discovery-token-ca-cert-hash sha256:2a196bbd77e4152a700d294a666e9d97336d0f7097f55e19a651c19e03d340a4
- 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
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
上面记录了完成的初始化输出的内容。
其中有以下关键内容:
生成token记录下来,后边使用kubeadm join往集群中添加节点时会用到
下面的命令是配置常规用户如何使用kubectl(客户端)访问集群,因为master节点也需要使用kubectl访问集群,所以也需要运行以下命令:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 1
- 2
- 3
最后给出了将节点加入集群的命令
kubeadm join 192.168.11.90:6443 --token hu2clf.898he8fnu64w3fur --discovery-token-ca-cert-hash sha256:2a196bbd77e4152a700d294a666e9d97336d0f7097f55e19a651c19e03d340a4
- 1
查看一下集群状态如下:
kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-0 Healthy {"health": "true"}
- 1
- 2
- 3
- 4
- 5
确认每个组件都处于healthy状态。
可能遇到的问题–net/http: TLS handshake timeout
如果报错主节点的6443端口无法连接,超时,拒绝连接。需要检查网络,一般来说 是因我们我们设置了http_proxy和https_proxy做代理翻墙导致不能访问自身和内网。
需要在/etc/profile中增加no_proxy参数后重试,或者重新init。
如下:
vi /etc/profile
- 1
在最后增加
export no_proxy='anjia0532,127.0.0.1,192.168.11.90,192.168.11.91,192.168.11.92,k8s.gcr.io,10.96.0.0/12,10.244.0.0/16,localhost'
- 1
保存退出。
让配置生效
source /etc/profile
- 1
如果仍然无效,重新init,因为init时会帮助我们去检查网络情况,一般init时没有警告是没问题的。
使用命令:
kubeadm reset
kubeadm init
- 1
- 2
集群初始化如果遇到问题,可以使用下面的命令进行清理再重新初始化:
kubeadm reset
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/
- 1
- 2
- 3
- 4
- 5
- 6
安装Pod Network (只在主节点执行)
接下来安装flannel network add-on:
mkdir -p ~/k8s/
cd ~/k8s
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl apply -f kube-flannel.yml
- 1
- 2
- 3
- 4
输出如下:
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
daemonset.extensions/kube-flannel-ds-amd64 created
daemonset.extensions/kube-flannel-ds-arm64 created
daemonset.extensions/kube-flannel-ds-arm created
daemonset.extensions/kube-flannel-ds-ppc64le created
daemonset.extensions/kube-flannel-ds-s390x created
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
这里可以cat查看kube-flannel.yml这个文件里的flannel的镜像的版本
cat kube-flannel.yml|grep quay.io/coreos/flannel
- 1
如果Node有多个网卡的话,目前需要在kube-flannel.yml中使用–iface参数指定集群主机内网网卡的名称,否则可能会出现dns无法解析。需要将kube-flannel.yml下载到本地,flanneld启动参数加上–iface=
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.10.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
- --iface=eth1
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
使用kubectl get pod –all-namespaces -o wide确保所有的Pod都处于Running状态。
[root@k8s k8s]# kubectl get pod --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
kube-system coredns-78fcdf6894-jf5tn 1/1 Running 0 6m 10.244.0.3 k8s <none>
kube-system coredns-78fcdf6894-ljmmh 1/1 Running 0 6m 10.244.0.2 k8s <none>
kube-system etcd-k8s 1/1 Running 0 5m 192.168.11.90 k8s <none>
kube-system kube-apiserver-k8s 1/1 Running 0 5m 192.168.11.90 k8s <none>
kube-system kube-controller-manager-k8s 1/1 Running 0 5m 192.168.11.90 k8s <none>
kube-system kube-flannel-ds-amd64-fvpj7 1/1 Running 0 4m 192.168.11.90 k8s <none>
kube-system kube-proxy-c8rrg 1/1 Running 0 6m 192.168.11.90 k8s <none>
kube-system kube-scheduler-k8s 1/1 Running 0 5m 192.168.11.90 k8s <none>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
master node参与工作负载 (只在主节点执行)
使用kubeadm初始化的集群,出于安全考虑Pod不会被调度到Master Node上,也就是说Master Node不参与工作负载。
这里搭建的是测试环境可以使用下面的命令使Master Node参与工作负载:
k8s是master节点的hostname
允许master节点部署pod,使用命令如下:
kubectl taint nodes --all node-role.kubernetes.io/master-
- 1
输出如下:
node "k8s" untainted
- 1
输出error: taint “node-role.kubernetes.io/master:” not found错误忽略。
禁止master部署pod
kubectl taint nodes k8s node-role.kubernetes.io/master=true:NoSchedule
- 1
测试DNS (只在主节点执行)
使用命令
kubectl run curl --image=radial/busyboxplus:curl -i --tty
- 1
输出如下:
If you don't see a command prompt, try pressing enter.
[ root@curl-87b54756-vsf2s:/ ]$
- 1
- 2
进入后执行
nslookup kubernetes.default
- 1
确认解析正常,输出如下:
[ root@curl-87b54756-vsf2s:/ ]$ nslookup kubernetes.default
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: kubernetes.default
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
- 1
- 2
- 3
- 4
- 5
- 6
输入
exit;
- 1
可退出image。
向Kubernetes集群添加Node (只在副节点执行)
下面我们将k8s1这个主机添加到Kubernetes集群中,在k8s1上执行之前的加入语句:
kubeadm join 192.168.11.90:6443 --token hu2clf.898he8fnu64w3fur --discovery-token-ca-cert-hash sha256:2a196bbd77e4152a700d294a666e9d97336d0f7097f55e19a651c19e03d340a4
- 1
正确加入输出如下:
[root@k8s1 ~]# kubeadm join 192.168.11.90:6443 --token hu2clf.898he8fnu64w3fur --discovery-token-ca-cert-hash sha256:2a196bbd77e4152a700d294a666e9d97336d0f7097f55e19a651c19e03d340a4
[preflight] running pre-flight checks
[WARNING RequiredIPVSKernelModulesAvailable]: the IPVS proxier will not be used, because the following required kernel modules are not loaded: [ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh] or no builtin kernel ipvs support: map[ip_vs:{} ip_vs_rr:{} ip_vs_wrr:{} ip_vs_sh:{} nf_conntrack_ipv4:{}]
you can solve this problem with following methods:
1. Run 'modprobe -- ' to load missing kernel modules;
2. Provide the missing builtin kernel ipvs support
I0815 16:53:55.675009 2758 kernel_validator.go:81] Validating kernel version
I0815 16:53:55.675090 2758 kernel_validator.go:96] Validating kernel config
[discovery] Trying to connect to API Server "192.168.11.90:6443"
[discovery] Created cluster-info discovery client, requesting info from "https://192.168.11.90:6443"
[discovery] Requesting info from "https://192.168.11.90:6443" again to validate TLS against the pinned public key
[discovery] Cluster info signature and contents are valid and TLS certificate validates against pinned roots, will use API Server "192.168.11.90:6443"
[discovery] Successfully established connection with API Server "192.168.11.90:6443"
[kubelet] Downloading configuration for the kubelet from the "kubelet-config-1.11" ConfigMap in the kube-system namespace
[kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[preflight] Activating the kubelet service
[tlsbootstrap] Waiting for the kubelet to perform the TLS Bootstrap...
[patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s1" as an annotation
This node has joined the cluster:
* Certificate signing request was sent to master and a response
was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the master to see this node join the cluster.
- 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
下面在master节点上执行命令查看集群中的节点:
[root@k8s k8s]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s Ready master 30m v1.11.2
k8s1 NotReady <none> 1m v1.11.2
k8s2 NotReady <none> 1m v1.11.2
[root@k8s k8s]#
- 1
- 2
- 3
- 4
- 5
- 6
如果副节点是NotReady,可以使用命令检查是否有报错
systemctl status kubelet.service
- 1
使用命令检查pod是否是running状态
[root@k8s kubernetes]# kubectl get pod --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
default curl-87b54756-vsf2s 1/1 Running 1 1h 10.244.0.4 k8s <none>
kube-system coredns-78fcdf6894-jf5tn 1/1 Running 0 2h 10.244.0.3 k8s <none>
kube-system coredns-78fcdf6894-ljmmh 1/1 Running 0 2h 10.244.0.2 k8s <none>
kube-system etcd-k8s 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-apiserver-k8s 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-controller-manager-k8s 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-flannel-ds-amd64-8p2px 0/1 Init:0/1 0 1h 192.168.11.91 k8s1 <none>
kube-system kube-flannel-ds-amd64-fvpj7 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-flannel-ds-amd64-p6g4w 0/1 Init:0/1 0 1h 192.168.11.92 k8s2 <none>
kube-system kube-proxy-c8rrg 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-proxy-hp4lj 0/1 ContainerCreating 0 1h 192.168.11.92 k8s2 <none>
kube-system kube-proxy-tn2fl 0/1 ContainerCreating 0 1h 192.168.11.91 k8s1 <none>
kube-system kube-scheduler-k8s 1/1 Running 0 2h 192.168.11.90 k8s <none>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
如果卡在ContainerCreating状态和Init:0/1一般也是副节点的镜像获取不到的问题,请回到 准备镜像小节。
准备好镜像之后一般很快就会变成running状态如下:
[root@k8s kubernetes]# kubectl get pod --all-namespaces -o wide
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
default curl-87b54756-vsf2s 1/1 Running 1 1h 10.244.0.4 k8s <none>
kube-system coredns-78fcdf6894-jf5tn 1/1 Running 0 2h 10.244.0.3 k8s <none>
kube-system coredns-78fcdf6894-ljmmh 1/1 Running 0 2h 10.244.0.2 k8s <none>
kube-system etcd-k8s 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-apiserver-k8s 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-controller-manager-k8s 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-flannel-ds-amd64-8p2px 1/1 Running 0 1h 192.168.11.91 k8s1 <none>
kube-system kube-flannel-ds-amd64-fvpj7 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-flannel-ds-amd64-p6g4w 1/1 Running 0 1h 192.168.11.92 k8s2 <none>
kube-system kube-proxy-c8rrg 1/1 Running 0 2h 192.168.11.90 k8s <none>
kube-system kube-proxy-hp4lj 1/1 Running 0 1h 192.168.11.92 k8s2 <none>
kube-system kube-proxy-tn2fl 1/1 Running 0 1h 192.168.11.91 k8s1 <none>
kube-system kube-scheduler-k8s 1/1 Running 0 2h 192.168.11.90 k8s <none>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
此时查看nodes也已经变成了ready状态
[root@k8s kubernetes]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s Ready master 2h v1.11.2
k8s1 Ready <none> 1h v1.11.2
k8s2 Ready <none> 1h v1.11.2
[root@k8s kubernetes]#
- 1
- 2
- 3
- 4
- 5
- 6
如果副节点也需要使用kubectl命令则需要把conf文件复制过去,使用命令
mkdir -p $HOME/.kube
sudo cp -i admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 1
- 2
- 3
如何从集群中移除Node
如果需要从集群中移除k8s2这个Node执行下面的命令:
在master节点上执行:
kubectl drain k8s2 --delete-local-data --force --ignore-daemonsets
kubectl delete node k8s2
- 1
- 2
在k8s2上执行:
kubeadm reset
ifconfig cni0 down
ip link delete cni0
ifconfig flannel.1 down
ip link delete flannel.1
rm -rf /var/lib/cni/
- 1
- 2
- 3
- 4
- 5
- 6
到这里我们就算成功安装好了k8s集群了。
一般来说 我们 还需要安装dashboard监控界面。
可参考文章:
k8s—dashboardv1.8.3版本安装详细步骤
CentOS系统中直接使用yum安装
给yum源增加一个Repo
[virt7-docker-common-release]
name=virt7-docker-common-release
baseurl=http://cbs.centos.org/repos/virt7-docker-common-release/x86_64/os/
gpgcheck=0
- 1
- 2
- 3
- 4
安装docker、kubernetes、etcd、flannel一步到位
yum -y install --enablerepo=virt7-docker-common-release kubernetes etcd flannel
- 1
安装好了之后需要修改一系列配置文件。
这个repo在CentOS7.3下是毫无意义的,因为CentOS官方源的extras中已经包含了Kubernetes1.5.2,如果你使用的是CentOS7.3的话,会自动下载安装Kubernetes1.5.2(Till March 30,2017)。如果你使用的是CentOS7.2的化,这个源就有用了,但是不幸的是,它会自动下载安装Kubernentes1.1。我们现在要安装目前的最新版本Kubernetes1.6,而使用的又是CentOS7.2,所以我们不使用yum安装(当前yum源支持的最高版本的kuberentes是1.5.2)。
使用二进制文件安装
这种方式安装的话,需要自己一个一个组件的安装。
首先需要分配好哪些节点安装什么组件和服务。
master/node需要安装以下服务:
kube-apiserver kube-controller-manager kube-scheduler kubelet kube-proxy etcd flannel kubectl docker
node需要安装以下服务
node kubectl kube-proxy flannel docker
安装Docker
yum localistall ./docker-engine*
- 1
将使用CentOS的extras repo下载docker。
关闭防火墙和SELinux
这是官网上建议的,我是直接将iptables-services和firewlld卸载掉了。
setenforce 0
systemctl disable iptables-services firewalld
systemctl stop iptables-services firewalld
- 1
- 2
- 3
安装etcd
下载二进制文件
DOWNLOAD_URL=https://storage.googleapis.com/etcd #etcd存储地址
ETCD_VER=v3.1.5 #设置etcd版本号
wget ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xvf etcd-${ETCD_VER}-linux-amd64.tar.gz
- 1
- 2
- 3
- 4
部署文件
将如下内容写入文件 /etc/etcd/etcd.conf 中:
# [member]
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
# ETCD_WAL_DIR=""
# ETCD_SNAPSHOT_COUNT="10000"
# ETCD_HEARTBEAT_INTERVAL="100"
# ETCD_ELECTION_TIMEOUT="1000"
# ETCD_LISTEN_PEER_URLS="http://localhost:2380"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
# ETCD_MAX_SNAPSHOTS="5"
# ETCD_MAX_WALS="5"
# ETCD_CORS=""
#
# [cluster]
# ETCD_INITIAL_ADVERTISE_PEER_URLS="http://localhost:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
# ETCD_INITIAL_CLUSTER="default=http://localhost:2380"
# ETCD_INITIAL_CLUSTER_STATE="new"
# ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://0.0.0.0:2379"
# ETCD_DISCOVERY=""
# ETCD_DISCOVERY_SRV=""
# ETCD_DISCOVERY_FALLBACK="proxy"
# ETCD_DISCOVERY_PROXY=""
#
# [proxy]
# ETCD_PROXY="off"
# ETCD_PROXY_FAILURE_WAIT="5000"
# ETCD_PROXY_REFRESH_INTERVAL="30000"
# ETCD_PROXY_DIAL_TIMEOUT="1000"
# ETCD_PROXY_WRITE_TIMEOUT="5000"
# ETCD_PROXY_READ_TIMEOUT="0"
#
# [security]
# ETCD_CERT_FILE=""
# ETCD_KEY_FILE=""
# ETCD_CLIENT_CERT_AUTH="false"
# ETCD_TRUSTED_CA_FILE=""
# ETCD_PEER_CERT_FILE=""
# ETCD_PEER_KEY_FILE=""
# ETCD_PEER_CLIENT_CERT_AUTH="false"
# ETCD_PEER_TRUSTED_CA_FILE=""
# [logging]
# ETCD_DEBUG="false"
# examples for -log-package-levels etcdserver=WARNING,security=DEBUG
# ETCD_LOG_PACKAGE_LEVELS=""
将 etcd, etcdctl放入 /usr/bin/下,并将如下内容写进/usr/lib/systemd/system/etcd.service文件
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
WorkingDirectory=/var/lib/etcd/
EnvironmentFile=-/etc/etcd/etcd.conf
User=etcd
# set GOMAXPROCS to number of processors
ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd --name=\"${ETCD_NAME}\" --data-dir=\"${ETCD_DATA_DIR}\" --listen-client-urls=\"${ETCD_LISTEN_CLIENT_URLS}\""
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
- 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
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
启动并校验
systemctl start etcd
systemctl enable etcd
systemctl status etcd
etcdctl ls
- 1
- 2
- 3
- 4
集群
若要部署多节点集群也比较简单,只要更改etcd.conf文件以及etcd.service添加相应配置即可
安装flannel
可以直接使用yum install flannel安装。
因为网络这块的配置比较复杂,我将在后续文章中说明。
安装Kubernetes
根据《Kubernetes权威指南(第二版)》中的介绍,直接使用GitHub上的release里的二进制文件安装。
执行下面的命令安装。
wget https://github.com/kubernetes/kubernetes/releases/download/v1.6.0/kubernetes.tar.gz
tar kubernetes.tar.gz
cd kubernetes
./cluster/get-kube-binaries.sh
cd server
tar xvf kubernetes-server-linux-amd64.tar.gz
rm -f *_tag *.tar
chmod 755 *
mv * /usr/bin
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
从下面的地址下载kubernetes-server-linux-amd64.tar.gz
https://storage.googleapis.com/kubernetes-release/release/v1.6.0
- 1
解压完后获得的二进制文件有:
cloud-controller-manager
hyperkube
kubeadm
kube-aggregator
kube-apiserver
kube-controller-manager
kubectl
kubefed
kubelet
kube-proxy
kube-scheduler
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
在cluster/juju/layers/kubernetes-master/templates目录下有service和环境变量配置文件的模板,这个模板本来是为了使用juju安装写的。
Master节点的配置
Master节点需要配置的kubernetes的组件有:
kube-apiserver
kube-controller-manager
kube-scheduler
kube-proxy
kubectl
- 1
- 2
- 3
- 4
- 5
配置kube-apiserver
编写/usr/lib/systemd/system/kube-apiserver.service文件。CentOS中的service配置文件参考
[Unit]
Description=Kubernetes API Service
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
After=etcd.service
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_ETCD_SERVERS \
$KUBE_API_ADDRESS \
$KUBE_API_PORT \
$KUBELET_PORT \
$KUBE_ALLOW_PRIV \
$KUBE_SERVICE_ADDRESSES \
$KUBE_ADMISSION_CONTROL \
$KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
- 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
创建kubernetes的配置文件目录/etc/kubernetes。
添加config配置文件。
###
# kubernetes system config
#
# The following values are used to configure various aspects of all
# kubernetes services, including
#
# kube-apiserver.service
# kube-controller-manager.service
# kube-scheduler.service
# kubelet.service
# kube-proxy.service
# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"
# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"
# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"
# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://sz-pg-oam-docker-test-001.tendcloud.com:8080"
添加apiserver配置文件。
###
## kubernetes system config
##
## The following values are used to configure the kube-apiserver
##
#
## The address on the local server to listen to.
KUBE_API_ADDRESS="--address=sz-pg-oam-docker-test-001.tendcloud.com"
#
## The port on the local server to listen on.
KUBE_API_PORT="--port=8080"
#
## Port minions listen on
KUBELET_PORT="--kubelet-port=10250"
#
## Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:2379"
#
## Address range to use for services
KUBE_SERVICE_ADDREKUBELET_POD_INFRA_CONTAINERSSES="--service-cluster-ip-range=10.254.0.0/16"
#
## default admission control policies
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
#
## Add your own!
#KUBE_API_ARGS=""
- 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
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
—admission-control参数是Kubernetes的安全机制配置,这些安全机制都是以插件的形式用来对API Serve进行准入控制,一开始我们没有配置ServiceAccount,这是为了方便集群之间的通信,不需要进行身份验证。如果你需要更高级的身份验证和鉴权的话就需要加上它了。
配置kube-controller-manager
编写/usr/lib/systemd/system/kube-controller.service文件。
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/controller-manager
ExecStart=/usr/bin/kube-controller-manager \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
在/etc/kubernetes目录下添加controller-manager配置文件。
###
# The following values are used to configure the kubernetes controller-manager
# defaults from config and apiserver should be adequate
# Add your own!
KUBE_CONTROLLER_MANAGER_ARGS=""
- 1
- 2
- 3
- 4
- 5
- 6
- 7
配置kube-scheduler
编写/usr/lib/systemd/system/kube-scheduler.service文件。
[Unit]
Description=Kubernetes Scheduler Plugin
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/scheduler
ExecStart=/usr/bin/kube-scheduler \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_SCHEDULER_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
在/etc/kubernetes目录下添加scheduler文件。
###
# kubernetes scheduler config
# default config should be adequate
# Add your own!
KUBE_SCHEDULER_ARGS=""
- 1
- 2
- 3
- 4
- 5
- 6
- 7
配置kube-proxy
编写/usr/lib/systemd/system/kube-proxy.service文件。
[Unit]
Description=Kubernetes Kube-Proxy Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/proxy
ExecStart=/usr/bin/kube-proxy \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
在/etc/kubernetes目录下添加proxy配置文件。
###
# kubernetes proxy config
# default config should be adequate
# Add your own!
KUBE_PROXY_ARGS=""
- 1
- 2
- 3
- 4
- 5
- 6
- 7
配置kubelet
创建配置
/usr/lib/systemd/system/kubelet.service
- 1
文件的内容为:
[Unit]
Description=Kubernetes Kubelet Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service
[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBELET_API_SERVER \
$KUBELET_ADDRESS \
$KUBELET_PORT \
$KUBELET_HOSTNAME \
$KUBE_ALLOW_PRIV \
$KUBELET_POD_INFRA_CONTAINER \
$KUBELET_ARGS
Restart=on-failure
[Install]
WantedBy=multi-user.target
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
在/etc/kubernetes目录下添加kubelet配置文件。
###
## kubernetes kubelet (minion) config
#
## The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=0.0.0.0"
#
## The port for the info server to serve on
KUBELET_PORT="--port=10250"
#
## You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=sz-pg-oam-docker-test-001.tendcloud.com"
#
## location of the api-server
KUBELET_API_SERVER="--api-servers=http://sz-pg-oam-docker-test-001.tendcloud.com:8080"
#
## pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
#
## Add your own!
KUBELET_ARGS=""
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
⚠️KUBELET_POD_INFRA_CONTAINER在生产环境中配置成自己私有仓库里的image。
Node节点配置
Node节点需要配置:
kube-proxy
kubectl
kube-proxy的配置与master节点的kube-proxy配置相同。
kubectl的配置需要修改KUBELET_HOST为本机的hostname,其它配置相同。
启动
在Master节点上执行:
for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler kube-proxy kubelet flanneld; do
systemctl restart $SERVICES
systemctl enable $SERVICES
systemctl status $SERVICES
done
- 1
- 2
- 3
- 4
- 5
在另外两台Node节点上执行:
for SERVICES in kube-proxy kubelet flanneld; do
systemctl restart $SERVICES
systemctl enable $SERVICES
systemctl status $SERVICES
done
- 1
- 2
- 3
- 4
- 5
验证
在Master节点上运行
$kubectl get all
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
svc/kubernetes 10.254.0.1 <none> 443/TCP 1h
$kubectl get nodes
NAME STATUS AGE VERSION
sz-pg-oam-docker-test-001.tendcloud.com Ready 7m v1.6.0
sz-pg-oam-docker-test-002.tendcloud.com Ready 4m v1.6.0
sz-pg-oam-docker-test-003.tendcloud.com Ready 10s v1.6.0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
现在可以正常使用啦。
kubeadm 生成的token过期后,集群增加节点
解决方法如下:
重新生成新的token
[root@walker-1 kubernetes]# kubeadm token create
[kubeadm] WARNING: starting in 1.8, tokens expire after 24 hours by default (if you require a non-expiring token use --ttl 0)
aa78f6.8b4cafc8ed26c34f
[root@walker-1 kubernetes]# kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
aa78f6.8b4cafc8ed26c34f 23h 2017-12-26T16:36:29+08:00 authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
- 1
- 2
- 3
- 4
- 5
- 6
获取ca证书sha256编码hash值
[root@walker-1 kubernetes]# openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'
0fd95a9bc67a7bf0ef42da968a0d55d92e52898ec37c971bd77ee501d845b538
- 1
- 2
节点加入集群
[root@walker-4 kubernetes]# kubeadm join --token aa78f6.8b4cafc8ed26c34f --discovery-token-ca-cert-hash sha256:0fd95a9bc67a7bf0ef42da968a0d55d92e52898ec37c971bd77ee501d845b538 172.16.6.79:6443 --skip-preflight-checks
- 1
转载请注明出处:kubernetes—CentOS7安装kubernetes1.11.2图文完整版
其他参考链接
官方安装文档可以参考 https://kubernetes.io/docs/setup/independent/install-kubeadm/
使用kubeadm在CentOS 7上安装Kubernetes 1.8
转载请注明出处:kubernetes—CentOS7安装kubernetes1.11.2图文完整版
——————— 作者:张小凡vip 来源:CSDN 原文:https://blog.csdn.net/zzq900503/article/details/81710319?utm_source=copy 版权声明:本文为博主原创文章,转载请附上博文链接!