一、网络的配置
方法一:手动配置
你可以手动的来部署pod网络和service网络(容器引擎以docker为例):
- 在k8s的1.11版本以上的node节点,首先,你需要调用lvs工具使用命令来创建nat的规则:指定访问<service ip>地址的某个端口,转发到pod内部地址
- 设置node节点的物理网卡,使用工具(太多,自己网上找)来实现<service ip>地址的overlay层叠网络
- 设置docker容器的网络,
docker network create -d overlay ...
添加一个层叠网络,然后将容器内的网卡分配进去,形成容器件的层叠网络
上面设置好以后,配置会自动通过连接api server最终存储到etcd中去。但是上面的配置过程十分的复杂,除非你对网络十分的属性
方法二:使用网络环境工具
由于pod网络和service网络配置十分复杂,而k8s实际上有着CNI的网络标准接口。市场上有很多网络环境工具,配置并运行后,直接就是一个pod网络和service网络环境,我们可以通过运行这些网络环境工具
让pod和service直接加入网络环境,这样就不用自己配置网络了,你只需要稍微配置一下工具,让你的pod和service加入到环境中去即可(其实工具配置通常就是需要你把node节点ip与service、pod相对应即可)。
常见的网络环境工具有
- flannel
完整的网络配置,形成一个完善的pod网络和service网络环境
- calico
完整的网络配置和网络策略,在形成一个完善的pod网络和service网络环境前提下,又提供了网络的隔离,可以让pod之间不在互通。但是此工具的配置也不简单
- cannel
结合上面两者的优点,形成一个完善的pod网络和service网络环境又提供了网络的隔离,配置还不复杂
二、部署
前面已经详细的介绍了kubernetes的结构和网络,部署kubernetes就是将master端和node端的组件部署上,把网络部署好(通常会使用网络环境工具)即可运行kubernetes。当然,这里的部署也分为2种办法:
手动部署介绍
将kubernetes集群的master和node各个组件下载并安装,然后以deamon的形式启动。最后使用网络环境工具部署好网络,通常使用flannel工具
使用部署工具部署介绍
kubernetes有很多的部署工具,有基于ansible的部署工具,有专门在特定的云主机(aws、谷歌云)上的部署工具kops。这里只介绍一个kubernetes官方的部署工具:kuberadm
kuberadm 在部署kubernetes时,master端的api server、scheduler调度器组件、control manager控制管理器组件,都是通过开启一个pod静态static容器来提供服务
由于master端的组件都由pod提供的容器来服务,因此使用kubeadm部署方法master也会装上kubelet和docker(容器引擎)
使用kubeadm来部署kubernetes
kubeadm部署流程需要注意k8s与docker的版本匹配和镜像拉取的问题,此外,建议使用新一点的docker版本。yum源上面的docker版本过于老旧了,不支持部署最新的k8s
部署前的准备
在部署kubernetes集群前,你得先做好集群部署的准备:
节点hosts文件的主机名最好能够相互解析
每个节点的时间需要同步,否则容易出问题
每个节点的防火墙,必须要先关闭:
iptables -F
根据前面的kubeadm部署的结构图所知,不论是master端还是node端,都需要创建pod容器(master为静态、node为动态),因此都会需要3个组件:kubelet容器实际管理组件、容器引擎docker(最好是最新版)
、kubeadm集群部署工具。除此之外,还可以安装一个kubernetes的客户端命令工具:kubectl
此外,kubeadm在部署master时,会下载master组件(api server、scheduler、control manager等)的镜像,但是镜像在国外无法拉取,因此要想办法获取到镜像
kubernetes集群的所有节点上都需要进行一次准备工作,具体过程如下:
配置阿里的yum源
配置docker-ce的yum源
代码语言:shell复制cat <<EOF > /etc/yum.repos.d/docker-ce.repo
[docker-ce-stable]
name=Docker CE Stable - $basearch
baseurl=https://download.docker.com/linux/centos/7/$basearch/stable
enabled=1
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-stable-debuginfo]
name=Docker CE Stable - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/stable
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-stable-source]
name=Docker CE Stable - Sources
baseurl=https://download.docker.com/linux/centos/7/source/stable
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-edge]
name=Docker CE Edge - $basearch
baseurl=https://download.docker.com/linux/centos/7/$basearch/edge
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-edge-debuginfo]
name=Docker CE Edge - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/edge
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-edge-source]
name=Docker CE Edge - Sources
baseurl=https://download.docker.com/linux/centos/7/source/edge
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-test]
name=Docker CE Test - $basearch
baseurl=https://download.docker.com/linux/centos/7/$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-test-debuginfo]
name=Docker CE Test - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-test-source]
name=Docker CE Test - Sources
baseurl=https://download.docker.com/linux/centos/7/source/test
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-nightly]
name=Docker CE Nightly - $basearch
baseurl=https://download.docker.com/linux/centos/7/$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-nightly-debuginfo]
name=Docker CE Nightly - Debuginfo $basearch
baseurl=https://download.docker.com/linux/centos/7/debug-$basearch/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
[docker-ce-nightly-source]
name=Docker CE Nightly - Sources
baseurl=https://download.docker.com/linux/centos/7/source/nightly
enabled=0
gpgcheck=1
gpgkey=https://download.docker.com/linux/centos/gpg
EOF
配置kubernetes for kubeadm的yum源
代码语言:shell复制cat <<EOF > /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
生成yum缓存
代码语言:shell复制yum clean all
yum makecache
节点上yum安装kubelet pod管理工具、kubeadm部署工具、docker-ce版本、kuberctl k8s客户端命令工具
代码语言:shell复制yum install docker-ce kubeadm kubectl kubelet
#安装完成后,使docker和kubelet自启动
systemctl enable docker kubelet
解决docker-ce下的一些错误和警告
docker-ce启动后,使用docker info有3个警告:
前2个是iptables未打开桥接的功能,因为在部署k8s时,因为要部署service所有得生成大量的iptables规则,其中就会用到iptables的桥接功能。因此需要打开iptables的桥接:
代码语言:shell复制echo 1 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 1 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
最后一个警告是xfs文件系统有个属性ftype设置有问题,应该设置为1(xfs_info /
命令可以查询)。因为overlay2文件系统格式需要底层xfs类型文件开启ftype,从而使overlayfs存储驱动支持d_type
这个问题有可能导致Docker在使用时报错。(如果overlayfs存储驱动不支持d_type的话,容器在操作文件系统时可能会出现一些奇怪的错误:比如在bootstrap的时候出现Chown error,或者rebuild时发生错误等等。)
解决办法为重新创建文件系统:
代码语言:shell复制umount <device路径> //device的路径可以在xfs_info中找到
#umount -l <device路径> //如果提示device is busy。强制卸载同时要重启
mkfs.xfs -n ftype=1 /<device路径> //重新格式化device,在此
mount <device路径> //重新挂载
xfs_info / //查看结果
拉取镜像
kubeadm部署k8s时需要的镜像文件由于某些原因,国内无法访问,因此需要想办法拿到相关的镜像文件
方法一(已经失效):
修改docker启动服务文件: vim /usr/lib/systemd/system/docker.service
#在[Service]标签下面添加
Environment="HTTPS_PROXY=http://www.ik8s.io:10080"
Environment="NO_PROXY=127.0.0.0/8,<内网地址>/24"
#添加完成后,reload
systemctl daemon-reload
systemctl restart docker
上诉代码的环境变量表示在访问除内网、本地所在的地址时,使用代理(先连接代理网站),通过代理网站来下载国外的kubeadm部署k8s需要的镜像
方法二: 使用Google的镜像站,然后修改标签
了解kubeadm安装的k8s版本需要那些版本的软件包(这个可以通过kubeadm init初始化一次看到)
我在执行kubeadm初始化时,因为拉取不到镜像产生了error,但是也知道了自己需要安装的软件版本,因此我可以去google的镜像网站去拉取:
代码语言:shell复制#google镜像网址拉取kubeadm部署k8s需要的镜像
docker pull mirrorgooglecontainers/kube-apiserver:v1.14.2
docker pull mirrorgooglecontainers/kube-controller-manager:v1.14.2
docker pull mirrorgooglecontainers/kube-scheduler:v1.14.2
docker pull mirrorgooglecontainers/kube-proxy:v1.14.2
docker pull mirrorgooglecontainers/pause:3.1
docker pull mirrorgooglecontainers/etcd:3.3.10
docker pull coredns/coredns:1.3.1
拉取好以后,修改tag标签的registry为”k8s.gcr.io“,这是kubeadm默认的镜像拉取registry地址:
代码语言:shell复制docker tag docker.io/mirrorgooglecontainers/kube-apiserver:v1.14.2 k8s.gcr.io/kube-apiserver:v1.14.2
docker tag docker.io/mirrorgooglecontainers/kube-controller-manager:v1.14.2 k8s.gcr.io/kube-controller-manager:v1.14.2
docker tag docker.io/mirrorgooglecontainers/kube-scheduler:v1.14.2 k8s.gcr.io/kube-scheduler:v1.14.2
docker tag docker.io/mirrorgooglecontainers/kube-proxy:v1.14.2 k8s.gcr.io/kube-proxy:v1.14.2
docker tag docker.io/mirrorgooglecontainers/pause:3.1 k8s.gcr.io/pause:3.1
docker tag docker.io/mirrorgooglecontainers/etcd:3.3.10 k8s.gcr.io/etcd:3.3.10
docker tag docker.io/coredns/coredns:1.3.1 k8s.gcr.io/coredns:1.3.1
建议本地在保存一份下载并更改好标签的kubeadm所需镜像:
代码语言:shell复制docker save -o kubeadm_need_images.tar k8s.gcr.io/kube-apiserver:v1.14.2 k8s.gcr.io/kube-controller-manager:v1.14.2 k8s.gcr.io/kube-scheduler:v1.14.2 k8s.gcr.io/kube-proxy:v1.14.2 k8s.gcr.io/pause:3.1 k8s.gcr.io/etcd:3.3.10 k8s.gcr.io/coredns:1.3.1
kubeadm下kubernetes集群master节点的初始部署
准备工作完成后,就可以初始化master端了
所谓master节点初始化,就是安装好master端的组件,然后配置master端,生成令牌,等待node节点的加入。
使用kubeadm init命令初始化k8s集群master节点
使用初始化命令:
代码语言:shell复制kubeadm init --kubernetes-version=v1.14.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --apiserver-advertise-address=<默认为0.0.0.0> --apiserver-bind-port=<默认为6443>
如上面命令,初始化时需要指定安装的k8s的版本,和k8s集群中的pod网络、service网络地址,而这里添的地址是为了配合fannel插件的k8s网络地址配置,如果要使用fannel就填上面的ip地址,这是fannel默认给k8s集群中的pod和service配置的网络地址
后面2个选择可以不加使用默认值
使用
kubeadm init --help
可以获取更多的参数详解
错误/警告的解决
执行初始化命令后,可能会遇到部分错误和警告信息,其中k8s版本和docker不兼容的警告或者错误需要自己去网上查询k8s和docker的匹配兼容版本,这里不做详解。其他常见错误/警告解决如下:
WARNNING信息:"Docker cgroup驱动程序不是systemd"
解决方法:
代码语言:shell复制vim /etc/docker/daemon.json
#修改内容为
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
systemctl restart docker
错误信息[ERROR Swap]: running with swap on is not supported. Please disable swap
解决方法:
修改/etc/sysconfig/kubelet文件
代码语言:shell复制vim /etc/sysconfig/kubelet
#修改后的内容为
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
然后 kubeadm init命令添加忽略选项:
kubeadm init --kubernetes-version=v1.14.2 --pod-network-cidr=10.244.0.0/16 --service-cidr=10.96.0.0/12 --ignore-preflight-errors=Swap
master节点kubeadm init后的部署
- 1.以普通用户权限,拷贝k8s的认证文件到自己的家目录,并更改文件所有权,具体代码输出结果上已经写的很清楚了
useradd chen #创建一个普通用户
echo "123456" |passed stdin chen #给用户配置密码
#vim /etc/sudoers #修改授权文件,给普通用户授权
visudo #修改授权文件,给普通用户授权
#在 ”root ALL=(ALL) ALL“下面添加一行:
chen ALL=(ALL) ALL
su - chen #切换到普通用户
#下面的代码按照kubeadm init 初始化后,在最后输出的信息。如 6.2.1最后图上所示
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf ~/.kube/config
sudo chown chen.chen ~/.kube/config
普通用户把凭证文件拷贝到家目录后,就可以使用kubectl客户端连接k8s的服务端了。注意:没有凭证文件的用户是无法使用kubectl连接到ks8服务端的,即使是root用户。测试chen普通用户是否能连接到k8s服务端:
代码语言:shell复制su - chen #切换到有凭证的用户
#使用kubectl客户端命令查看能连接到服务端(apiserver)
kubectl get nodes #查看集群中的各个节点
kubectl get ns #查看集群中的pod空间。多个pod可以归纳在一起称为pod的(名称)空间
kubectl get pods -n kube-system #kube-system是kubeadm把与系统相关的pod归纳到了此空间中
master端使用fannel配置网络
前面的步骤已经使用kubeadm已经将master端运行需要的组件都安装完毕,并且也配置好了kubectl客户端连接k8s服务端的凭证。现在缺少给pod配置网络
master端利fannel镜像开启一个pod容器,可以快速的将集群节点内的pod加入到一个网络环境中,这就组成了pod的网络
配置fannel网络在Kubernetes v1.7 版本以上只需要一条命令:(项目地址:https://github.com/coreos/flannel)
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
执行后,会自动拉取quay.io上的fannel镜像,拉取完后,kubelet会用fannel镜像启动一个pod,然后将节点上的pod加入同一个网络,即生成了一个pod网络
代码语言:shell复制kubectl get pods -n kube-system -o wide #查看系统的pod空间详细,可以看到fannel的网络
到了这步,master节点的初始部署就算完成了
kubeadm下kubernetes集群node节点加入到kubernetes集群
node节点和master一样要进行“kubeadm部署前的准备” 包括 kubeadm、docker-ce、kubelet、kubectl组件的安装和镜像的获取。
代码语言:shell复制除此,node节点也要处理maste端的警告信息:
Docker cgroup驱动程序不是systemd
和 错误信息:[ERROR Swap]: running with swap on is not supported. Please disable swap
#处理警告信息
vim /etc/docker/daemon.json
#修改内容为
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
systemctl restart docker
#处理错误信息
vim /etc/sysconfig/kubelet
#修改后的内容为
KUBELET_EXTRA_ARGS="--fail-swap-on=false"
初始化node节点
只需要执行一条kubeadm上的命令,加入到集群即可(注意处理swap错误):
代码语言:shell复制kubeadm join 192.168.0.201:6443 --token 23kp0e.4ah0aorx0gvglnb9
--discovery-token-ca-cert-hash sha256:a99ebb97a064ce9dd7704869fadb9c7ed78ed5883ff3c21eca64b00a4f079b5a
--ignore-preflight-errors=Swap
在加入时,可能会看到一个报错,这时需要在master端在生成一个tocken:
代码语言:shell复制kubeadm token create #master端执行
生成新的tocken后,node端使用新的tocken加入集群:
代码语言:shell复制kubeadm join 192.168.0.201:6443 --token kz8swt.4tbtlzwpyjzpq62g
--discovery-token-ca-cert-hash sha256:a99ebb97a064ce9dd7704869fadb9c7ed78ed5883ff3c21eca64b00a4f079b5a
--ignore-preflight-errors=Swap
node节点加入到集群后,使用命令:
代码语言:shell复制#su - chen
kubectl get nodes
详细描述节点信息:
代码语言:shell复制kubectl describe nodes <node名称>
初始化node节点
至此,kubernetes的基本部署算是完成了
补充说明
如果遇到在k8s集群中,当一个节点无法访问集群内其他节点的service或者pod地址时(尤其是在node节点重启后),通常会报以下错误:
代码语言:shell复制Failed connect to <节点的pod地址>/<节点的service地址>; No route to host
这个时候,需要你在无法访问的目标node节点上清除一下防火墙规则:
代码语言:shell复制iptables -F