链接:https://pan.baidu.com/s/1T71UbsgeDDhS8Y0gV3gblw
提取码:kf3y
( 下载后只需解压Kubernetes安装所需软件.zip.001就会自动解压002和003的文件夹 )
如何搭建Kubernetes集群及访问搭建好的集群
本次k8s集群安装拓扑结构:
一、软路由设置
1、新建一个虚拟机,虚拟磁盘必须选择 ide 模式
2、使用老毛桃iso文件作为新建虚拟机的启动盘,进入pe界面后,更改vmware光盘连接,载入软路由iso文件,在PE中打开我的电脑中->软路由iso文件,
3、写入完成后,断开vmware光盘连接,对pe系统关机,重新开机便会进入koolshare软路由界面
4、k8s网络拓扑结构:
( koolshare默认地址192.168.1.1,这个拓扑意思就是k8s节点设置网关地址为koolshare的地址,由koolshare经过ss代理访问k8s官方仓库,而koolshare有两张网卡,一个only host连接k8s节点,一个nat连接物理机 )
5、根据上面的拓扑,k8s节点网段设置为192.168.10.0/24,master节点设置为192.168.10.10,node1设置为192.168.10.20,node2设置为192.168.10.21,这就意味着软路由koolshare在k8s节点一旁的接口也得是192.168.10.0网段。但是koolshare默认是192.168.1.1,所以需要在物理机vmnet1的适配器设置一下。
( 192.168.1.240 意思就是:192.168.1.1 与koolshare接口地址冲突了,所以配置一个网关,如果别的虚拟机需要使用仅主机模式,可以设置其网关为192.168.1.240 )
( 192.168.10.240意思就是:在配置一个ip地址作为192.168.10.0网段的网关,作为k8s集群的软路由的网关出口 )
( 以上两个操作相当于设置了两个网关,两个出口 )
6、浏览器访问koolshare配置页面:192.168.1.1
默认密码:koolshare
接下来:
确认:
此处将192.168.1.1设置为192.168.10.1相当于将koolshare默认网卡接口192.168.1.1地址设置为192.168.10.1,即k8s节点的网关地址
二、安装kubeadm前提准备
( 如果未采用软路由方式,网关直接设置仅主机vmnet1的网卡地址就可以了 )
master1、node1、node2三个节点仅主机模式通过软路由上网:
1、设置各个节点的主机名以及Host文件的解析
2、安装依赖包
# yum -y install conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git
3、关闭centos7默认的防火墙firewalld并启用iptables
# systemctl stop firewalld && systemctl disable firewalld
# yum -y install iptables-service
# systemctl start iptables
# systemctl enable iptables
# 清除iptables规则,并保存
# iptables -F && service iptables save
4、把虚拟内存永久关闭:
(原因是kubeadm在安装k8s,它在init初始化的时候会检测swap分区有没有关闭,它觉得如果虚拟内存是开启的话,pod将会放到虚拟内存中运行,会大大降低工作效率,所以他会要求将虚拟内存关闭)
# swapoff -a && sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
5、关闭Selinux:
# setenforce 0 && sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
6、调整内核参数:
① 编辑优化文件内容( 调整内核参数,对于k8s )
# cat > kubernetes.conf << EOF
> net.bridge.bridge-nf-call-iptables=1
> net.bridge.bridge-nf-call-ip6tables=1
> net.ipv4.ip_forward=1
> net.ipv4.tcp_tw_recycle=0
> vm.swappiness=0 #禁止使用 swap 空间,只有当系统 OOM 时才允许使用它
> vm.overcommit_memory=1 # 不检查物理内存是否够用
> vm.panic_on_oom=0 # 开启 OOM
> fs.inotify.max_user_instances=8192
> fs.inotify.max_user_watches=1048576
> fs.file-max=52706963
> fs.nr_open=52706963
> net.ipv6.conf.all.disable_ipv6=1
> net.netfilter.nf_conntrack_max=2310720
> EOF
② 将其放入/etc/sysctl.d/kubernetes.conf下,使其可以开机被调用
# cp kubernetes.conf /etc/sysctl.d/kubernetes.conf
( sysctl命令用于运行时配置内核参数,这些参数位于/proc/sys目录下。sysctl配置与显示在/proc/sys目录中的内核参数.可以用sysctl来设置或重新设置联网功能,如IP转发、IP碎片去除以及源路由检查等。用户只需要编辑/etc/sysctl.conf文件,即可手工或自动执行由sysctl控制的功能 )
③ 使用sysctl -p读取文件,使其立即生效
( sysctl -p 从指定的文件加载系统参数,如不指定即从/etc/sysctl.conf中加载 )
# sysctl -p /etc/sysctl.d/kubernetes.conf
7、调整系统时区
# 设置系统时区为中国/上海
timedatectl set-timezone Asia/Shanghai
# 将当前的 UTC 时间写入硬件时钟
timedatectl set-local-rtc 0
# 重启依赖于系统时间的服务
systemctl restart rsyslog
systemctl restart crond
8、设置日志系统
centos7之后,系统启动方式改为了systemd,所以默认有两个日志系统在工作:rsylogd和systemd journald,相比之下systemd journald更好一点,所以我们将其设置为第二个即可
# mkdir /var/log/journal # 持久化保存日志的目录
# mkdir /etc/systemd/journald.conf.d
# cat > /etc/systemd/journald.conf.d/99-prophet.conf <<EOF
[Journal]
# 持久化保存到磁盘
Storage=persistent
# 压缩历史日志
Compress=yes
SyncIntervalSec=5m
RateLimitInterval=30s
RateLimitBurst=1000
# 最大占用空间 10G
SystemMaxUse=10G
# 单日志文件最大 200M
SystemMaxFileSize=200M
# 日志保存时间 2 周
MaxRetentionSec=2week
# 不将日志转发到 syslog
ForwardToSyslog=no
EOF
# systemctl restart systemd-journal
9、升级内核为4.44
CentOS 7.x 系统自带的 3.10.x 内核存在一些 Bugs,导致运行的 Docker、Kubernetes 不稳定
# rpm -Uvhhttp://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
# 安装完成后检查 /boot/grub2/grub.cfg 中对应内核 menuentry 中是否包含 initrd16 配置,如果没有,再安装一次!
# yum --enablerepo=elrepo-kernel install -y kernel-lt
# 设置开机从新内核启动
grub2-set-default 'CentOS Linux (4.4.189-1.el7.elrepo.x86_64) 7 (Core)'
二、kubeadm部署安装
1、修改k8s的kube-proxy的调度方式:
① 加载模块
# modprobe br_netfilter
② 编写文件 ( 这里的依赖关系并不是rpm包,而是模块 )
# cat > /etc/sysconfig/modules/ipvs.modules << EOF
> #!/bin/bash
> modprobe -- ip_vs
> modprobe -- ip_vs_rr
> modprobe -- ip_vs_wrr
> modprobe -- ip_vs_sh
> modprobe -- nf_conntrack_ipv4
> EOF
③ 赋予755权限并执行文件
# chmod 755 /etc/sysconfig/modules/ipvs.modules
# bash /etc/sysconfig/modules/ipvs.modules
④ 查看模块是否导入成功
# lsmod | grep -e ip_vs -e nf_conntrack_ipv4
2、安装docker软件
① 安装docker的依赖包
# yum install -y yum-utils device-mapper-persistent-data lvm2
② 添加阿里云的docker-ce镜像仓库
# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
③ 更新系统并安装docker-ce
最新版本会用到overlay2的驱动引擎,这个驱动引擎会更有效的增加镜像的存储能力
# yum update -y && yum install -y docker-ce
注意:
安装docker-ce完成之后,重启虚拟机,启动之后使用uname -r,如果因为优先级关系发现内核版本变回了3.1,启用4.4的版本,并重新启动
# grub2-set-default 'CentOS Linux (4.4.189-1.el7.elrepo.x86_64) 7 (Core)'
# reboot
④ 配置daemon.json
# mkdir /etc/docker
# cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
EOF
# 第一行设置docker的默认cgroup组为systemd
( 默认情况下centos7下有两个cgroup组,一个是cgroupfs,一个是systemd管理的cgroup,所以为了统一化,我们就设置docker的cgroup组为systemd管理的cgroup去进行cgroup隔离。 )
# 后面几行的意思是,把docker存储日志的方式改为json-file文件存储类型,并且存储大小为100MB.
这几行配置的意义在于:后期我们可以通过/var/log/ ... /去查找我们容器的对应日志信息,这样我们就可以在efk里搜索对应的索引信息了。
⑤ 创建目录去存放docker配置文件
# mkdir-p /etc/systemd/system/docker.service.d
⑥ 重启docker服务
# systemctl daemon-reload && systemctl restart docker && systemctl enable docker
三、安装Kubeadm( 主从配置 )
① 导入kubernetes阿里云仓库
# cat << EOF >/etc/yum.repos.d/kubernetes.repo
>[kubernetes]
>name=Kubernetes
>baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/k>ubernetes-el7-x86_64
>enabled=1
>gpgcheck=0
>repo_gpgcheck=0
>gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
>EOF
② 安装 初始化工具kubeadm、命令行管理工具kubectl、kubelet(与CRI交互创建容器)
# yum -y install kubeadm-1.15.1 kubectl-1.15.1 kubelet-1.15.1
③ 设置开机自启动kubelet
因为kubelet需要与容器接口交互启动容器,而k8s通过kubeadm安装出来以后都是以pod形式存在,也就是底层以容器的形式运行的。所以它一定是要开机自启的,否则重启服务器之后会发现集群可能没有启动。
# systemctl enable kubelet.service
④ kubeadm在初始化集群的时候,会从gce谷歌云服务器中pull所需要的镜像,速度就不用说了
所以我们先导入镜像:kubeadm-basic.images.tar.gz
⑤ 解压缩镜像包,并使用docker导入镜像
⑥ 使用一个sh脚本来完成导入镜像的工作:
# vim load-kubeadm-images.sh
#文本内容如下
#!/bin/bash
ls /root/kubeadm-basic.images > /tmp/image-list.txt
cd /root/kubeadm-basic.images
for i in $( cat /tmp/image-list.txt )
do
docker load -i $i
done
rm -rf /tmp/image-list.txt
脚本加权限:
# chmod +x load-kubeadm-images.sh
执行脚本:
⑦ 其他两个node节点也执行如上操作:
# scp -r kubeadm-basic.images load-kubeadm-images.sh root@k8s-node1:/root/
# scp -r kubeadm-basic.images load-kubeadm-images.sh root@k8s-node2:/root/
# k8s-node1# ./load-kubeadm-images.sh
# k8s-node2# ./load-kubeadm-images.sh
四、初始化主节点
# kubeadm config print init-defaults > kubeadm-config.yaml
# 红色部分:显示init默认配置文件,把它打印出来
① 这样就获得了kubeadm的默认配置模板,需要修改一下
# vim kubeadm-config.yaml
kubeadm-config.yaml配置文件内容:(缩进)
apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
- system:bootstrappers:kubeadm:default-node-token
token: abcdef.0123456789abcdef
ttl: 24h0m0s
usages:
- signing
- authentication
kind: InitConfiguration
localAPIEndpoint:
advertiseAddress: 192.168.10.10
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master1
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: k8s.gcr.io
kind: ClusterConfiguration
#################################################
kubernetesVersion: v1.15.1 #
#################################################
networking:
dnsDomain: cluster.local
#################################################
podSubnet: "10.211.0.0/16" #
#################################################
serviceSubnet: 10.96.0.0/12
scheduler: {}
---
##################################################
apiVersion: kubeproxy.config.k8s.io/v1alpha1 #
kind: KubeProxyConfiguration #
featureGates: #
SupportIPVSProxyMode: true #
mode: ipvs #
##################################################
默认我们会安装一个flanel的网络插件去实现覆盖性网络,它的默认podSubnet网段就是10.244.0.0/16,如果不一致,后期是需要修改的。
最后的字段就是将调度方式改为默认的ipvs
# kubeadm init --config=kubeadm-config.yaml --upload-certs | tee kubeadm-init.log
指定从kubeadm-config.yaml配置文件初始化安装,
-upload-certs自动颁发证书,在高可用节点比较有意义,本地搭建测试加不加无所谓
集群初始化完成之后,需要做一下几件事情:
1、在当前用户的家目录创建一个.kube目录,它会保存我们的连接配置( 也就是kubelet、kubectl与我们的kuber api使用https进行交互时产生的缓存 )以及配置文件
2、拷贝集群管理员的配置文件到这个目录下
3、把它的属者和属组授予当前的用户
# sudo chown $(id -u):$(id -g) $HOME/.kube/config
五、加入主节点master1
以上完成之后就可以查询我们现在有哪些节点了:
① wget 获取flannel配置文件
# mkdir install-k8s
# mv kubeadm-init.log kubeadm-config.yaml install-k8s/
# cd install-k8s/ &&ls
# mkdir core
# mv * core/
# mkdir plugin && cd plugin
# mkdir flannel && cd flannel
# wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# kubectl create -f kube-flannel.yml
kubectl是k8s的命令行管理工具,get pod获取pod状态,-n kube-system指定名称空间,如果不加-n默认使用的是default的名称空间。所有的系统组件默认都会被安装在kube-system名称空间下,所以要获取它的状态,必须加-n选项
# kubectl get pod -n kube-system
( 这时候我们已经可以看到flunnel网络插件了 )
# kubectl get node
部署完flannel之后,使用ifconfig会看到flannel.1的网卡:
因为已经有了扁平化的网络状态,所以节点状态就变为了Ready:
六、加入其它节点
加入其它节点的方法,其实我们可以在日志中看到:
① ( 在其他节点执行这条命令 )
② 在master节点查看节点信息:
# 通过查看更详细的信息,来查找各个组件的启动信息
# kubectl get pod -n kube-system -o wide
为了避免不断输入,更方便的方法:
( 在后边加上-w 参数,监视状态 )
# kubectl get pod -n kube-system -o wide -w
七、备份重要文件
略
配置私有仓库harbor:
八、harbor虚拟机安装docker
略
九、编辑docker配置文件daemon.json
默认docker仓库是一个https的访问,在我们自己搭建的环境下,没有必要购买https证书
就制作一个假的https证书,告诉k8s集群这个证书是安全的。
那也就意味着其他节点要是想使用这个证书,也得加入这行配置
① 都加完配置之后,重启docker
② 将我们准备的docker-compose文件导入harbor,并将其放入/usr/local/bin/目录下,为其加上x
③ 导入准备的harbor的安装压缩包
④ 将其解压后的文件夹放入/usr/local/下,避免误删
⑤ 修改配置文件harbor.cfg
⑥ 创建证书
# openssl genrsa -des3 -out server.key 2048
⑦ 创建一个证书的请求,csr
# openssl req -new -key server.key -out server.csr
⑧ 转换成证书
这一步的含义是:因为docker在引导的时候,使用的是nginx做引导的,所以在启动的时候如果你的证书,也就是私钥和证书是有密码的话,就会出现问题启动不成功。所以我们这一步就要退一下密码,我们的私钥里就不包含密码了。
⑨ 拿着证书请求去签名
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt
⑩ 上一步证书生成成功后,给所有证书加上x
# chmod a+x *
⑪ 每个节点都需要添加hub的主机解析
harbor
master
node1
node2
因为模拟环境,需要使用web界面,所以在物理机window下修改hosts文件,改文件需要管理员权限才能修改。推荐方式如下:
a、搜索记事本,以管理员身份运行
b、根据路径打开hosts文件
c、添加上解析地址,输入完之后回车一下
⑫ 执行安装脚本install.sh
./install.sh
( 我这里发生了报错 )
解决:
问题出在prepare文件上,于是我vim看了一下配置文件,首行#!/usr/bin/python,这是一个python脚本
原因:
因为之前我升级了python2版本到python3,所以需要改一下shebang,如下。
重新安装:
退回到harbor工作目录,即/usr/local/harbor/下
执行安装脚本,成功安装。
⑬ 物理机访问hub.k8s.com
因为我们的https证书是自己制作颁布的,所以它会提示不是安全连接: 账户:admin 密码:Harbor12345
账户密码其实可以在配置文件中修改:
十、
那我们的仓库既然已经弄好了,k8s集群到底能不能利用到这个仓库呢?
在k8s利用到之前,docker首先要利用到镜像仓库harbor,我们来测试一下:
① 登录仓库
② push镜像到仓库
a、我们看到如果要push到镜像仓库,必须要使用docker tag为其更改为如图所示位置的名称:
b、使用docker tag修改镜像名称
c、使用docker push推送到仓库
d、刷新web界面即可看到push上来的镜像
③ 将一个镜像push到harbor,并尝试启动pod利用push的镜像
a、编写一个Dockerfile文件,并使用docker build创建一个自己的镜像
b、修改此镜像的tag以能上传到指定harbor
# docker tag zjib/static-web:v1 \ hub.k8s.com/library/zjib/static-web:v1
c、将其推送到仓库:
d、push完成之后刷新web页面
e、接下来删除node1本地的镜像,避免master的scheduler在调度时发生干扰
f、此时看harbor仓库的下载次数还为0次
g、接下来就可以在master节点拉取镜像通过scheduler调度节点运行pod了
kubectl run --help即可查看如何运行pod
( 后期通过yaml资源清单启动实例 )
h、使用kubectl run命令运行pod
# kubectl run nginx-deployment \ --image=hub.k8s.com/library/zjiblinux/static-web:v1 \ --port=80 --replicas=1
# 红色的参数是指定deployment的名字,绿色的参数时指定镜像来源;蓝色的参数是指定副本个数
( 因为k8s是扁平化网络,所以加不加端口无所谓 )
i、使用kubectl get pod -owide可以详细看到pod的信息
j、既然看到是node2节点启动的pod,就去看一下
h、此时也可以看到harbor仓库的镜像已经被下载了一次
i、因为是处于扁平化的网络之下,所以可以直接根据pod的ip地址进行访问:
j、当你尝试删除pod的时候,你会发现:
删除了pod又新启动了一个新的pod。原因是什么呢?
答:因为在run deployment的时候,我们指定了replicas=1,也就是副本数目维持在1个,当你执行删除了唯一的pod,为了维持原来的数目,rs就会自动生成一个新的pod。
k、对副本数目进行扩容
# 先获取deployment的名字
# kubectl get deployment
# 进行扩容
# kubectl scale --replicas=3 deployment/名称
哪怕你重新删除pod,它还是会维护3个副本的数量
l、我们可以通过svc的方式来访问pod,通过暴露目标资源(资源可以是pod、rs、deployment、svc即service)为新的svc来达到访问pod的目的:
# kubectl get deployment
# kubectl expose –help
--help中给出了几个分别暴露deployment、pod、service等的模板:
# kubectl expose deployment nginx-deployment --port=10000 --target-port=80
# 创建一个svc,目标是nginx-deployment,将目标pod中的80端口连接到新创建service的10000端口
并且通过新创建的service来访问pod的话,是一种轮询机制,即现在有3个副本,访问时便会按序依次访问这3个副本。
通过ipvsadm -Ln与kubectl get node -owide对比
rr就是轮询机制,所以这里的svc机制是调度lvs实现的负载均衡,当你访问svc的10.103.230.207:10000的时候,就会轮询当前的3个pod副本
m、修改svc的TYPE类型
svc的ip地址是一个内部地址,外部进行访问肯定是不行的,如果有这种需求的话,可以通过修改svc的TYPE类型实现
#kubectl edit svc nginx-deployment
NodePort意思就是在所有的节点都暴露这么一个端口与之访问:( master1、node1、node2 )
master1节点:
node1节点:
参考来源:
尚硅谷汪洋老师视频