侧边栏壁纸
博主头像
枕头下放双臭袜子博主等级

今我何功德,曾不事农桑

  • 累计撰写 166 篇文章
  • 累计创建 32 个标签
  • 累计收到 0 条评论
k8s

kubernetes学习笔记四( 使用kubeadm搭建集群 )

枕头下放双臭袜子
2019-11-30 / 0 评论 / 0 点赞 / 703 阅读 / 0 字 / 正在检测是否收录...

链接:https://pan.baidu.com/s/1T71UbsgeDDhS8Y0gV3gblw
提取码:kf3y

( 下载后只需解压Kubernetes安装所需软件.zip.001就会自动解压002和003的文件夹 )

如何搭建Kubernetes集群及访问搭建好的集群

本次k8s集群安装拓扑结构:

image.png

一、软路由设置

  1、新建一个虚拟机,虚拟磁盘必须选择 ide 模式

image

image

image

image

  2、使用老毛桃iso文件作为新建虚拟机的启动盘,进入pe界面后,更改vmware光盘连接,载入软路由iso文件,在PE中打开我的电脑中->软路由iso文件,

image

  3、写入完成后,断开vmware光盘连接,对pe系统关机,重新开机便会进入koolshare软路由界面

image

  4、k8s网络拓扑结构:

( koolshare默认地址192.168.1.1,这个拓扑意思就是k8s节点设置网关地址为koolshare的地址,由koolshare经过ss代理访问k8s官方仓库,而koolshare有两张网卡,一个only host连接k8s节点,一个nat连接物理机 )

image

  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集群的软路由的网关出口 )

( 以上两个操作相当于设置了两个网关,两个出口 )

image

image

  6、浏览器访问koolshare配置页面:192.168.1.1

    默认密码:koolshare

image.png

image.png

image.png

接下来:

image.png

确认:

image.png

image.png

此处将192.168.1.1设置为192.168.10.1相当于将koolshare默认网卡接口192.168.1.1地址设置为192.168.10.1,即k8s节点的网关地址

image.png

image.png

image.png

image.png

image.png

image.png

image.png

二、安装kubeadm前提准备

( 如果未采用软路由方式,网关直接设置仅主机vmnet1的网卡地址就可以了 )

master1、node1、node2三个节点仅主机模式通过软路由上网:
image.png

image.png

  1、设置各个节点的主机名以及Host文件的解析

image.png

image.png

image.png

  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

image.png

  6、调整内核参数:

image.png

    ① 编辑优化文件内容( 调整内核参数,对于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

image.png

    ② 将其放入/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更好一点,所以我们将其设置为第二个即可

image.png

# 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)'

image.png

二、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

image.png

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

image.png

    ②  安装 初始化工具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导入镜像

image.png

    ⑥ 使用一个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

image.png

     脚本加权限:

     # 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自动颁发证书,在高可用节点比较有意义,本地搭建测试加不加无所谓

image.png

image.png

    集群初始化完成之后,需要做一下几件事情:

    1、在当前用户的家目录创建一个.kube目录,它会保存我们的连接配置( 也就是kubelet、kubectl与我们的kuber api使用https进行交互时产生的缓存 )以及配置文件

    2、拷贝集群管理员的配置文件到这个目录下

image.png

    3、把它的属者和属组授予当前的用户

    # sudo chown $(id -u):$(id -g) $HOME/.kube/config

image.png

五、加入主节点master1

    以上完成之后就可以查询我们现在有哪些节点了:

image.png

    ①  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

image.png

     kubectl是k8s的命令行管理工具,get pod获取pod状态,-n kube-system指定名称空间,如果不加-n默认使用的是default的名称空间。所有的系统组件默认都会被安装在kube-system名称空间下,所以要获取它的状态,必须加-n选项

     # kubectl get pod -n kube-system

    ( 这时候我们已经可以看到flunnel网络插件了 )

image.png

    # kubectl get node

    部署完flannel之后,使用ifconfig会看到flannel.1的网卡:

image.png

    因为已经有了扁平化的网络状态,所以节点状态就变为了Ready:

image.png

六、加入其它节点

    加入其它节点的方法,其实我们可以在日志中看到:

    ① ( 在其他节点执行这条命令 )

image.png

image.png

image.png

    ②  在master节点查看节点信息:

image.png

     # 通过查看更详细的信息,来查找各个组件的启动信息

     # kubectl get pod -n kube-system -o wide

image.png

     为了避免不断输入,更方便的方法:

     ( 在后边加上-w 参数,监视状态 )

     # kubectl get pod -n kube-system -o wide -w

七、备份重要文件

     略

配置私有仓库harbor:

八、harbor虚拟机安装docker

     略

九、编辑docker配置文件daemon.json

     默认docker仓库是一个https的访问,在我们自己搭建的环境下,没有必要购买https证书

     就制作一个假的https证书,告诉k8s集群这个证书是安全的。

image.png

     那也就意味着其他节点要是想使用这个证书,也得加入这行配置

    ①  都加完配置之后,重启docker

image.png

image.png

image.png

image.png

    ②  将我们准备的docker-compose文件导入harbor,并将其放入/usr/local/bin/目录下,为其加上x

image.png

    ③  导入准备的harbor的安装压缩包

image.png

    ④  将其解压后的文件夹放入/usr/local/下,避免误删

image.png

    ⑤  修改配置文件harbor.cfg

image.png

    ⑥  创建证书

    # openssl genrsa -des3 -out server.key 2048

image.png

    ⑦  创建一个证书的请求,csr

    # openssl req -new -key server.key -out server.csr

image.png

    ⑧  转换成证书

     这一步的含义是:因为docker在引导的时候,使用的是nginx做引导的,所以在启动的时候如果你的证书,也就是私钥和证书是有密码的话,就会出现问题启动不成功。所以我们这一步就要退一下密码,我们的私钥里就不包含密码了。

image.png

    ⑨  拿着证书请求去签名

     # openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

image.png

    ⑩  上一步证书生成成功后,给所有证书加上x

    # chmod a+x *

image.png

    ⑪  每个节点都需要添加hub的主机解析

harbor

image.png

master

image.png

node1

image.png

node2

image.png

    因为模拟环境,需要使用web界面,所以在物理机window下修改hosts文件,改文件需要管理员权限才能修改。推荐方式如下:

        a、搜索记事本,以管理员身份运行

        b、根据路径打开hosts文件

        c、添加上解析地址,输入完之后回车一下

    ⑫  执行安装脚本install.sh

./install.sh

    ( 我这里发生了报错 )

image.png

解决:

    问题出在prepare文件上,于是我vim看了一下配置文件,首行#!/usr/bin/python,这是一个python脚本

原因:

    因为之前我升级了python2版本到python3,所以需要改一下shebang,如下。

image.png

重新安装:

image.png

    退回到harbor工作目录,即/usr/local/harbor/下

    执行安装脚本,成功安装。

    ⑬  物理机访问hub.k8s.com

image.png

    因为我们的https证书是自己制作颁布的,所以它会提示不是安全连接: 账户:admin 密码:Harbor12345

image.png

    账户密码其实可以在配置文件中修改:

image.png

十、

    那我们的仓库既然已经弄好了,k8s集群到底能不能利用到这个仓库呢?

    在k8s利用到之前,docker首先要利用到镜像仓库harbor,我们来测试一下:

    ①  登录仓库

image.png

    ②  push镜像到仓库

image.png

image.png

        a、我们看到如果要push到镜像仓库,必须要使用docker tag为其更改为如图所示位置的名称:

image.png

        b、使用docker tag修改镜像名称

image.png

        c、使用docker push推送到仓库

image.png

        d、刷新web界面即可看到push上来的镜像

image.png

    ③  将一个镜像push到harbor,并尝试启动pod利用push的镜像

        a、编写一个Dockerfile文件,并使用docker build创建一个自己的镜像

image.png

image.png

image.png

        b、修改此镜像的tag以能上传到指定harbor

# docker tag zjib/static-web:v1   \ hub.k8s.com/library/zjib/static-web:v1

image.png

        c、将其推送到仓库:

image.png

        d、push完成之后刷新web页面

image.png

        e、接下来删除node1本地的镜像,避免master的scheduler在调度时发生干扰

image.png

        f、此时看harbor仓库的下载次数还为0次

image.png

        g、接下来就可以在master节点拉取镜像通过scheduler调度节点运行pod了

        kubectl run --help即可查看如何运行pod

        ( 后期通过yaml资源清单启动实例 )

image.png

        h、使用kubectl run命令运行pod

        # kubectl run nginx-deployment \ --image=hub.k8s.com/library/zjiblinux/static-web:v1 \ --port=80 --replicas=1

        # 红色的参数是指定deployment的名字,绿色的参数时指定镜像来源;蓝色的参数是指定副本个数

        ( 因为k8s是扁平化网络,所以加不加端口无所谓 )

image.png

        i、使用kubectl get pod -owide可以详细看到pod的信息

image.png

        j、既然看到是node2节点启动的pod,就去看一下

image.png

        h、此时也可以看到harbor仓库的镜像已经被下载了一次

image.png

        i、因为是处于扁平化的网络之下,所以可以直接根据pod的ip地址进行访问:

image.png

        j、当你尝试删除pod的时候,你会发现:

image.png

    删除了pod又新启动了一个新的pod。原因是什么呢?

    答:因为在run deployment的时候,我们指定了replicas=1,也就是副本数目维持在1个,当你执行删除了唯一的pod,为了维持原来的数目,rs就会自动生成一个新的pod。

        k、对副本数目进行扩容

        # 先获取deployment的名字

        # kubectl get deployment

        # 进行扩容

        # kubectl scale --replicas=3 deployment/名称

image.png

        哪怕你重新删除pod,它还是会维护3个副本的数量

        l、我们可以通过svc的方式来访问pod,通过暴露目标资源(资源可以是pod、rs、deployment、svc即service)为新的svc来达到访问pod的目的:

        # kubectl get deployment

        # kubectl expose –help

        --help中给出了几个分别暴露deployment、pod、service等的模板:

image.png

        # kubectl expose deployment nginx-deployment --port=10000 --target-port=80

        # 创建一个svc,目标是nginx-deployment,将目标pod中的80端口连接到新创建service的10000端口

image.png

    并且通过新创建的service来访问pod的话,是一种轮询机制,即现在有3个副本,访问时便会按序依次访问这3个副本。

    通过ipvsadm -Lnkubectl get node -owide对比

image.png

    rr就是轮询机制,所以这里的svc机制是调度lvs实现的负载均衡,当你访问svc的10.103.230.207:10000的时候,就会轮询当前的3个pod副本

        m、修改svc的TYPE类型

        svc的ip地址是一个内部地址,外部进行访问肯定是不行的,如果有这种需求的话,可以通过修改svc的TYPE类型实现

        #kubectl edit svc nginx-deployment

image.png

image.png

        NodePort意思就是在所有的节点都暴露这么一个端口与之访问:( master1、node1、node2 )

    master1节点:

image.png

image.png

    node1节点:

image.png

image.png

参考来源:
尚硅谷汪洋老师视频

0

评论