Kubernetes v1.19 课程笔记
创想云教育Kubernetes v1.19 认证管理员培训-2020-1-4
Kubernetes 认证管理员培训
CKA= Certified Kubernetes Administrator 偏运维方向
CKA 考试时间3小时 25道练习题
CKAD= Certified Kubernetes Application Developer 偏开发方向
CKAD 考试时间2小时 19道练习题
考点:
核心概念 10%
理解k8s api 术语
理解k8s 架构
理解services和其它网络相关术语
Installation , Configuration & Validation 安装,配置和验证 10%
设计一个k8s集群
安装k8s master 和 nodes
配置高可用的k8s集群
选择一个网络方案
k8s集群验证
Application Liecycle Management 应用生命周期管理 10%
理解Deployment
了解各种配置应用方式
应用扩容
应用自愈相关概念
Network 网络 10%
k8s集群网络配置
理解pod的网络概念 docker网络概念
理解service networking
部署和配置网络负载均衡
Storage 存储 10%
掌握持久化卷(PV) 如何创建PV
掌握持久化卷请求(PVC) 如何创建PVC
掌握Volumes Access Mode
如何为容器应用配置持久化存储
应用:
有状态应用mysql 无状态应用 php
Scheduling 调度 10%
使用label选择器来调试pods
Resource limit 会影响pod调度
各种调度器有什么作用
Logging / Monitoring 日志和监控 10%
掌握如何监控k8s集群组件
如何监控容器应用
管理集群组件日志
组件日志如何集中管理
管理应用日志
Cluster Maintenance 集群维护 10%
k8s集群升级流程
备份和还原
Troubleshooting 问题排查 10%
排查应用失败故障
node 故障 master 故障
排查网络故障
Security 安全 10%
掌握如何配置认证和授权
k8s 安全相关术语
定义安全上下文
Linux:
用户管理(useradd usermod userdel) 软件包管理(yum rpm dnf)
网络管理(nmcli hostnamectl netstate route ) 磁盘管理(fdisk mkfs pvcreate vgcreate lvcreate)
日志管理(rsyslog systemd-journal logrotate) 定时任务(at crontab )
文件管理(cp mv touch mkdir rsync scp vim)
Docker等容器运行时的基本原理
docker 环境信息 info version
docker 容器生命周期管理 create |
exec run start stop restart kill rm
docker 运维命令 ps top export port rename
docker 镜像仓库 login search pull push
docker 资源管理 volume network
docker 日志信息 logs history events
环境搭建:
VMware Workstation 实验环境
2. Kubernetes基本概念
什么是Kubernetes:
Kubernetes(k8s)是自动化容器操作的开源平台
操作:部署,调度,集群节点扩展
用过Docker容器技术部署容器,将Docker看成Kubernetes内部使用的低级别的组件
Kubernetes不仅仅支持Docker Rocket
PAAS OpenShift S2I Source 2 Image (Docker Image ) K8S+Docker
Kubernetes(k8s):
自动化容器的部署和复制
随时扩展或收缩容器应用
将容器组织成组,并且提供容器间的负载均衡
提供容器弹性,如果容器失效就替换
为什么需要Kubernetes(k8s): 开源容器集群管理系统
docker container 某个玩具
一组container编排起来,每次出去玩(启动某个服务)更方便
开源容器集群管理系统:
实现容器集群自动化部署,自动扩容,收缩,维护
故障迁移:当某个node节点故障,node节点上的服务会自动迁移到另外node节点上
过程所有服务无中断,这是Docker不能做到
K8S集群机器分成两类: 1 Master 节点 运行K8S集群管理组件 etcd 用于持久化存储集群中所有资源对象 node service pod rc namespace apiserver 提供了资源对象唯一操作入口 scheduler 集群调度器负责调度pod在集群中哪个节点上运行 controller Manager K8S集群内部管理控制中心 实现整个K8S集群资源管理 POD调度 弹性伸缩 安全控制 全部自动完成
2 Node Kubeproxy 实现了service的负载均衡器 Kubelet 负责pod生命周期管理创建 监控 删除同时kublet上报本节点状态信息到apiserver Docker 容器引擎 三个组件 负责本节点上的Pod的生命周期的管理
|
资源调度: 当某个node节点上的cpu memory资源不够的时候,扩容node,新创建pod就会被kube-scheduler调度到新的node节点
3. Kubernetes 架构及原理
为什么Kubernetes组件仅通过Kubernetes API相互交互:
创建Pod,非常方便让Pod引用卷,为什么会有PersistentVolumeCalim PVC对象?
原则:
1 声明式而非命令式
Start Containers |
Node1 |
Node2 |
通过一条命令,启动容器:
容器在node1运行,节点1故障 用户监控每一个节点,每一个POD状态,如果出现异常,所有故障处理交给用户来做
Kubernetes API 是声明式而非命令式
命令式:
用户:输入命令
系统:执行命令
通过一条命令,启动容器,用户执行命令,交给系统 ,监控用户来做
声明式:API支持自动恢复
用户:定义期望值,期望pod应该运行1个
系统:按照用户期望的状态去运行
Start Containers 用户创建一个API对象 kubctl create –f xxxx.ymal |
Node2 pod1 在节点2上运行 |
Node1 pod 故障 |
Kubernetes设计原则:
声明式(非祈使式) 例:要1个10G的Ceph volume
循环,持续达成结果 例:好的,我去Ceph找1个不小于10G的volume,找不到,一会儿重试或者创建一块
简单,做尽可能少的事情(类微服务) 例:我负责找到10G volume,但我不负责挂载,有其他人负责
模块化(组件化,接口化,插件化) 例:基于Kubernetes接口创建Ceph volume,也可以创建GlusterFS
兼容Legacy应用(不需要改变应用来适应平台) 例:升级Kubernetes集群不要求升级平台上应用
开源(开放代码,开放标准) 例: RESTful,JSON
Kubernetes 架构客户端服务端架构:
客户端:
通过Restful接口或直接使用kubectl命令和Kubernetes集群进行通信
每个K8S集群由一组Master或一组node节点组成
Master: 负责存储K8S集群的状态并为Kubernetes对象分配和调度资源
Master: 三个重要组件构成
管理整个K8S集群,所有管理组件都是运行在Master节点,负责接收客户端请求,调度容器的执行
scheduler: 调度器
调度器为Kubernetes中运行的POD容器选择部署的Node节点,根据用户的需要选择满足用户需求的节点来运行Pod
apiserver:
apiserver负责处理来自用户的请求,主要作用对外提供Restful接口
包含用于查看集群状态的请求以及改变集群状态的写请求,也是唯一一个与etcd集群通信的组件
controller:
运行一系列控制器进程,这些进程会按照用户期望值在后台不断调节整个K8S集群中的对象
当服务的状态发生变化,控制器就会发现这个改变,开始向目标状态迁移
Node: 计算节点 两个重要组件
kubelet
kubelet 是我们node节点上一个非常重要服务
1 向Master节点发送自己的健康状况
2 从apiserver 接收新的或修改的pod规范,并且保证节点上pod和其它容器正常运行
每个节点都会启动kublet进程:
用来处理Master节点下发的任务,管理pod
kubelet 会在API Server上注册节点信息,定期向Master节点发送自己的健康状况以及资源状态
总结:
理解成一个agent Node节点上pod管家
kube-proxy 代理服务
负责主机的子网管理,同时也可以将服务暴露给外部
在多个隔离的网络中把请求转发给正确Pod
流程:
用户通过kubectl提交一个创建RC的请求(Replication Controller) RC定义了一个期望的场景,声明pod副本数量,该请求通过API Server写入到etcd,此时controller Manager通过API Server的监听到了这个RC的事件,根据RC里pod模板生成一个pod对象,通过API Server写入到etcd,事件被scheduler发现,立即执行一个非常复杂调度流程,为pod选择一个node,然后通过API Server写入到etcd,目标node上的kubelet 进程通过API Server监测新的pod,按照它的定义,启动pod
pod 模板:
apiVersion: v1
kind: ReplicationController
metadata:
name: webserver
spec:
replicas: 2
etcd: coreos 开发的高可用分布式的数据库
etcd 在整个k8s集群中非常非常重要的组件:
保存整个K8S集群的所有网络配置和对象状态信息
用于持久化存储集群中所有资源对象node service pod rc namespace
所有数据都是存储在etcd中,如果etcd发生故障将会导致整个集群不可用
生产环境:
etcd一定要做高可用
数据做好备份
Kubernetes要求集群网络具备如下条件:
所有Pods之间可以相互通信
所有Pods和nodes可以相互通信
不做NAT
list-watch 工作机制:k8s统一异步消息传递
etcd 存储整个集群的数据 apiserver 作为统一的入口 任何对数据的操作都必须经过apserver
kubelet 通过list-watch监听api server中的资源 (pod/rs/rc)
list-watch
list 调用资源的list api 基于http短链接实现
watch 调用资源的watch pai 基于http长链接实现
每当用户使用kubectl创建一个RC对象后,controller-manager都是通过list-watch这种方式得到rc对象
scheduler/kubelet 也是通过list-watch 获取数据,处理请求
K8S组件之间采用http协议通信,没有依赖中间件 OpenStack AMQP RabbitMQ
客户端组件: controller manager scheduler kubelet 轮询apiserver
apiserver 通知客户端,如果采用轮询,apiserver压力非常大,实时性很低
如果apiserver主动发http请求,很难保证消息可靠性
K8S 采用list-watch 统一的异步消息处理机制 1 保证消息实时性 可靠性
消息系统:
1 消息可靠性 2 消息实时性 3 消息顺序性 4 高性能
首先消息必须是可靠的,list和watch一起保证消息可靠性
list api可以查询当前资源及对应的状态(用户期望状态)
客户端通过期望状态和实际状态进行比较
watch api 和 apiserver 保持一个长链接,接收资源的状态变更并做相应处理
消息必须实时的:
list-watch机制下,每当apiserver的资源产生状态变更,将事件及时推送给客户端,保证了消息的实时性
Kubernetes pod:
pod 是Kubernetes中能够创建和部署的计算最小单元,是Kubernetes集群中一个应用的实例
Pod 中包含一个或多个容器,还包括存储,网络等各个容器共享资源
单容器pod 常见部署方式
一个pod代表着集群中运行的一个进程
FTPServer |
Volume |
POD |
多容器pod 一个pod内的容器共享IP址址和端口 容器之间可以通过localhost互相访问
Pod 可以独立运行的服务单元,简化了应用部署的难度,以更高的抽象层次为应用部署提供了极大的方便
Pod分成两类:
1 自主式pod 不能自我修复 当pod创建后 pod运行在node1 node1故障
2 控制器管理的pod
配置文件: pod配置信息有以下几部分组成”
apiVersion kind metadata spec status
apiVersion kind 固定值
$ kubeclt create -f webserver.yml kubectl get pod webserver –o yaml
vim webserver.yml
apiVersion: v1
kind: Pod
metadata:
name: webserver
labels:
spec:
containers:
- name: xxxx
image: docker.io/nginx
Pod的生命周期
Pending:Pod已经被Kubernetes系统接纳,但Pod里至少有1个容器还没有被创建成功
Pod已创建,通常情况下正在下载镜像
Running:Pod已经被分配到node,所有容器被创建,至少1个容器在running或是starting, restarting
Failed:Pod里的所有容器已被终止,至少1个容器终止失败
Succeeded:Pod里的所有容器都被成功终止,不会被restarted
Unknown:Pod状态不能被获取,如:Pod不能和Host通信等 通常都是网络问题
如何对Pod进行健康检测:三种方式
Kubernetes利用Handler功能,可以对容器进行检测:
1 在容器执行命令
2 检查容器端口是否可以连接
3 检查http请求状态是否正常
4. Kubernetes安装和配置
单master多node:测试使用
Kubernetes安装方式有很多种:
1 kubeadm 官方推荐部署方式 一套完成脚本封装 Centos Ubuntu Debian RHEL Container Linux
2 kubespary 基于ansible部署方案 也支持OpenStack VMware vSphere
安装部署K8S集群 |
||
部署方式 kubeadm kubespary 单独配置一个Ansible |
||
主机 操作系统 配置 IP |
||
master |
CentOS 7 |
2VCPU 4G 192.168.1.41 |
Node1 |
CentOS 7 |
2VCPU 2G 192.168.1.51 |
Node2 |
CentOS 7 |
2VCPU 2G 192.168.1.61 |
Harbor |
CentOS7 |
2VCPU 1G 192.168.1.71 |
Storage |
CentOS7 |
2VCPU 1G 192.168.1.81 |
虚拟化软件: VMware® Workstation 16 Pro 16.0.0 build-16894299
k8s版本: k8s.1.19.0.tar
On Master:
[root@k8s-master ~]# hostnamectl set-hostname k8s-master.cloudshelledu.com
[root@k8s-master ~]# nmcli connection modify eno16777736 ipv4.addresses 192.168.1.40/24 ipv4.gateway 192.168.1.1 ipv4.dns 119.29.29.29 ipv4.method manual
[root@k8s-master ~]# sed -i 's/^ONBOOT=.*/ONBOOT=yes/' /etc/sysconfig/network-scripts/ifcfg-eno16777736
[root@k8s-master ~]# nmcli connection up eno16777736
[root@k8s-master ~]# yum install bash* -y
[root@k8s-master ~]# exit
[root@k8s-master ~]# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.1.40 k8s-master.cloudshelledu.com k8s-master
192.168.1.50 k8s-node1.cloudshelledu.com k8s-node1
192.168.1.60 k8s-node2.cloudshelledu.com k8s-node2
[root@k8s-master ~]# ssh-keygen 生成一对密钥
[root@k8s-master ~]# ssh-copy-id root@k8s-node1
[root@k8s-master ~]# ssh-copy-id root@k8s-node2
[root@k8s-master ~]# ssh-copy-id root@k8s-master
On Node1:
[root@k8s-node1 ~]# hostnamectl set-hostname k8s-node1.cloudshelledu.com
[root@k8s-node1 ~]# nmcli connection modify eno16777736 ipv4.addresses 192.168.1.50/24 ipv4.gateway 192.168.1.1 ipv4.dns 119.29.29.29 ipv4.method manual
[root@k8s-node1 ~]# sed -i 's/^ONBOOT=.*/ONBOOT=yes/' /etc/sysconfig/network-scripts/ifcfg-eno16777736
[root@k8s-node1 ~]# nmcli connection up eno16777736
[root@k8s-node1 ~]# yum install bash* -y
[root@k8s-node1 ~]# exit
On Node2:
[root@k8s-node2 ~]# hostnamectl set-hostname k8s-node1.cloudshelledu.com
[root@k8s-node2 ~]# nmcli connection modify eno16777736 ipv4.addresses 192.168.1.60/24 ipv4.gateway 192.168.1.1 ipv4.dns 119.29.29.29 ipv4.method manual
[root@k8s-node2 ~]# sed -i 's/^ONBOOT=.*/ONBOOT=yes/' /etc/sysconfig/network-scripts/ifcfg-eno16777736
[root@k8s-node2 ~]# nmcli connection up eno16777736
[root@k8s-node2 ~]# yum install bash* -y
[root@k8s-node2 ~]# exit
安装k8s集群依赖的软件包
[root@k8s-master ~]# yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git –y
配置防火墙使用iptables/netfilter
[root@k8s-master ~]# systemctl stop firewalld.service
[root@k8s-master ~]# systemctl disable firewalld.service
[root@k8s-master ~]# systemctl mask firewalld.service
Created symlink from /etc/systemd/system/firewalld.service to /dev/null.
[root@k8s-master ~]# yum install iptables-services –y
[root@k8s-master ~]# systemctl start iptables
[root@k8s-master ~]# systemctl enable iptables
[root@k8s-master ~]# iptables –F 把防火墙所有规则删除,允许所有
[root@k8s-master ~]# service iptables save 保存防火墙规则
关闭SELinux 安全增强型Linux 保护服务安全性通过策略
[root@k8s-master ~]# setenforce 0
[root@k8s-master ~]# sed -i 's/^SELINUX=.*/SELINUX=disable/' /etc/selinux/config
系统优化,修改内核参数
cat > k8s.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
vm.overcommit_memory=1
vm.panic_on_oom=0
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.nv_conntrack_max=2310720
EOF
[root@k8s-master ~]# mv k8s.conf /etc/sysctl.d/
[root@k8s-master ~]# sysctl -f /etc/sysctl.d/k8s.conf
升级内核: 3.10内核有一些bugs,导致Docker引擎不稳定
[root@k8s-master ~]# yum -y install https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
[root@k8s-master ~]# yum --enablerepo=elrepo-kernel install kernel-lt –y
[root@k8s-master ~]# grub2-set-default 'CentOS Linux (5.4.86-1.el7.elrepo.x86_64) 7 (Core)'
kube-proxy 开启ipvs模块 lvs集群的核心模块
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
[root@k8s-master ~]# chmod 755 /etc/sysconfig/modules/ipvs.modules
[root@k8s-master ~]# bash /etc/sysconfig/modules/ipvs.modules
[root@k8s-master ~]# lsmod |grep -e ip_vs
ip_vs_sh 16384 0
ip_vs_wrr 16384 0
ip_vs_rr 16384 0
安装Docker引擎:
[root@k8s-master ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@k8s-master ~]# mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
EOF
[root@k8s-master ~]# mkdir /etc/systemd/system/docker.service.d
[root@k8s-master ~]# wget https://download.docker.com/linux/centos/docker-ce.repo -O /etc/yum.repos.d/ docker-ce.repo
[root@k8s-master ~]# yum install docker-ce –y
[root@k8s-master ~]# systemctl daemon-reload
[root@k8s-master ~]# systemctl restart docker
[root@k8s-master ~]# systemctl enable docker
安装kubeadm配置YUM源,启动kubelet 在master node1 node2
On Master:
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
[root@k8s-master ~]# yum install kubelet kubeadm kubectl –y
[root@k8s-master ~]# yum remove kubelet kubeadm kubectl –y 默认安装最新版本软件
[root@k8s-master ~]# yum install -y kubelet-1.19.0-0 kubeadm-1.19.0-0 kubectl-1.19.0-0 –y 指定版本
[root@k8s-master ~]# systemctl enable kubelet.service
On Node1 Node2: 安装K8S集群依赖
[root@k8s-node1 ~]# yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git –y
[root@k8s-node2 ~]# yum install -y conntrack ntpdate ntp ipvsadm ipset jq iptables curl sysstat libseccomp wget vim net-tools git –y
Node1: 防火墙配置
[root@k8s-node1 ~]# systemctl stop firewalld.service
[root@k8s-node1 ~]# systemctl disable firewalld.service
[root@k8s-node1 ~]# systemctl mask firewalld.service
[root@k8s-node1 ~]# yum install iptables-services –y
[root@k8s-node1 ~]# systemctl start iptables
[root@k8s-node1 ~]# systemctl enable iptables
[root@k8s-node1 ~]# iptables -F
[root@k8s-node1 ~]# service iptables save
Node2: 防火墙配置
[root@k8s-node2 ~]# systemctl stop firewalld.service
[root@k8s-node2 ~]# systemctl disable firewalld.service
[root@k8s-node2 ~]# systemctl mask firewalld.service
[root@k8s-node2 ~]# yum install iptables-services –y
[root@k8s-node2 ~]# systemctl start iptables
[root@k8s-node2 ~]# systemctl enable iptables
[root@k8s-node2 ~]# iptables -F
[root@k8s-node2 ~]# service iptables save
On Node1 Node2 SELinux:
[root@k8s-node1 ~]# setenforce 0
[root@k8s-node1 ~]# sed -i 's/^SELINUX=.*/SELINUX=disable/' /etc/selinux/config
[root@k8s-node2 ~]# setenforce 0
[root@k8s-node2 ~]# sed -i 's/^SELINUX=.*/SELINUX=disable/' /etc/selinux/config
系统优化,修改内核参数
On Node1
cat > k8s.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
vm.overcommit_memory=1
vm.panic_on_oom=0
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.nv_conntrack_max=2310720
EOF
[root@k8s-node1 ~]# mv k8s.conf /etc/sysctl.d/
[root@k8s-node1 ~]# sysctl -f /etc/sysctl.d/k8s.conf
On Node2
cat > k8s.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
vm.overcommit_memory=1
vm.panic_on_oom=0
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.nv_conntrack_max=2310720
EOF
[root@k8s-node2 ~]# mv k8s.conf /etc/sysctl.d/
[root@k8s-node2 ~]# sysctl -f /etc/sysctl.d/k8s.conf
On Node1:
升级内核: 3.10内核有一些bugs,导致Docker引擎不稳定
yum -y install https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
yum --enablerepo=elrepo-kernel install kernel-lt –y
grub2-set-default 'CentOS Linux (4.4.248-1.el7.elrepo.x86_64) 7 (Core)'
On Node2:
升级内核: 3.10内核有一些bugs,导致Docker引擎不稳定
yum -y install https://www.elrepo.org/elrepo-release-7.0-4.el7.elrepo.noarch.rpm
yum --enablerepo=elrepo-kernel install kernel-lt –y
grub2-set-default 'CentOS Linux (4.4.248-1.el7.elrepo.x86_64) 7 (Core)'
On Node1:
kube-proxy 开启ipvs模块 lvs集群的核心模块
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
chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules
lsmod |grep -e ip_vs
On Node2:
kube-proxy 开启ipvs模块 lvs集群的核心模块
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
chmod 755 /etc/sysconfig/modules/ipvs.modules
bash /etc/sysconfig/modules/ipvs.modules
lsmod |grep -e ip_vs
安装Docker引擎 Node1:
yum install -y yum-utils device-mapper-persistent-data lvm2
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF 修改docker cgroup驱动,与k8s一致,使用systemd
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
EOF
mkdir /etc/systemd/system/docker.service.d
wget https://download.docker.com/linux/centos/docker-ce.repo -O /etc/yum.repos.d/ docker-ce.repo
yum install docker-ce –y
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
安装Docker引擎 Node2:
yum install -y yum-utils device-mapper-persistent-data lvm2
mkdir /etc/docker
cat > /etc/docker/daemon.json <<EOF
{
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
}
}
EOF
mkdir /etc/systemd/system/docker.service.d
yum install docker-ce –y
systemctl daemon-reload
systemctl restart docker
systemctl enable docker
安装kubeadm配置YUM源,启动kubelet 在node1 node2
On Node1 Node2:
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 install -y kubelet-1.19.0-0 kubeadm-1.19.0-0 kubectl-1.19.0-0 –y 指定版本
systemctl enable kubelet.service
初始化K8S集群: 导入镜像
On Master:
[root@k8s-master k8s-tools]# ls
docker-compose k8s.1.19.0.tar.gz
flannel.v0.12.0-amd64.tar kubeadm-basic.images.tar.gz
harbor-offline-installer-v1.7.4.tgz
[root@k8s-master k8s-tools]# tar xzvf k8s.1.19.0.tar.gz
[root@k8s-master k8s-tools]# vim local-image.sh
#!/bin/bash
ls /k8s-tools/k8s > /tmp/list.txt
cd /k8s-tools/k8s
for i in $(cat /tmp/list.txt)
do
docker load -i $i
done
[root@k8s-master k8s-tools]# chmod 755 local-image.sh
[root@k8s-master k8s-tools]# ./local-image.sh
225df95e717c: Loading layer 336.4kB/336.4kB
96d17b0b58a7: Loading layer 45.02MB/45.02MB
[root@k8s-master ~]# scp -r /k8s-tools/ root@k8s-node1:/
[root@k8s-master ~]# scp -r /k8s-tools/ root@k8s-node2:/
On Node1 Node2:
[root@k8s-node1 ~]# cd /k8s-tools/
[root@k8s-node1 k8s-tools]# ./local-image.sh
225df95e717c: Loading layer 336.4kB/336.4kB
96d17b0b58a7: Loading layer 45.02MB/45.02MB
[root@k8s-node2 ~]# cd /k8s-tools/
[root@k8s-node2 k8s-tools]# ./local-image.sh
225df95e717c: Loading layer 336.4kB/336.4kB
96d17b0b58a7: Loading layer 45.02MB/45.02MB
在master初始化主节点:
使用kubeadm 初始集群要从Google GCE云服务器下载镜像,非常慢,需要提前导入镜像
[root@k8s-master ~]# kubeadm config print init-defaults > kubeadm-config.yaml
[root@k8s-master ~]# vi 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.1.40
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master.cloudshelledu.com
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: registry.cn-hangzhou.aliyuncs.com/google_containers
kind: ClusterConfiguration
kubernetesVersion: v1.19.0
networking:
dnsDomain: cluster.local
podSubnet: 10.244.0.0/16 添加一行
serviceSubnet: 10.96.0.0/12
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
featureGates:
SupportIPVSProxyMode: true
mode: ipvs
在Master Node1 Node2 关闭交换分区:
swapoff -a;sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
开始初始化k8s集群:
[root@k8s-master ~]# kubeadm init --config=kubeadm-config.yaml --upload-certs |tee kubeadm-init.log
[root@k8s-master ~]# less kubeadm-init.log
[addons] Applied essential addon: CoreDNS
[addons] Applied essential addon: kube-proxy
Your Kubernetes control-plane has initialized successfully!
在master当前用户Home目录下创建一个隐藏目录.kube,目录保存连接配置kubectl 和kubeapi进行https通信,有一些缓存需要保存以及一些证书文件
[root@k8s-master ~]# mkdir -p $HOME/.kube
[root@k8s-master ~]# sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
[root@k8s-master ~]# sudo chown $(id -u):$(id -g) $HOME/.kube/config
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master.cloudshelledu.com NotReady master 5m36s v1.19.0
NotReady 需要扁平化的网络,目前k8s还没有构建flannel网络插件
[root@k8s-master k8s-tools]# docker load < flannel.v0.12.0-amd64.tar
[root@k8s-master k8s-tools]# kubectl create -f kube-flannel.yaml
查看flannel是否部署成功,默认是kube-system 命名空间
[root@k8s-master k8s-tools]# kubectl get pods -n kube-system
[root@k8s-master ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master.cloudshelledu.com Ready master 5m36s v1.19.0
将node1 node2 节点添加到主节点之前导入镜像:
[root@k8s-node1 k8s-tools]# docker load < flannel.v0.12.0-amd64.tar
[root@k8s-node2 k8s-tools]# docker load < flannel.v0.12.0-amd64.tar
[root@k8s-node1 k8s-tools]# kubeadm join 192.168.1.40:6443 --token abcdef.0123456789abcdef --discovery-token-ca-cert-hash sha256:4fd246005107336732bf68bf7a585a4473fbe8cc4edc8add8c99802ffe9c1c4f
[root@k8s-node2 k8s-tools]# kubeadm join 192.168.1.40:6443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:4fd246005107336732bf68bf7a585a4473fbe8cc4edc8add8c99802ffe9c1c4f
验证命令:看到K8S集群三个节点,节点状态 Ready
[root@k8s-master k8s-tools]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master.cloudshelledu.com Ready master 29m v1.19.0
k8s-node1.cloudshelledu.com Ready <none> 5m44s v1.19.0
k8s-node2.cloudshelledu.com Ready <none> 104s v1.19.0
[root@k8s-master k8s-tools]# kubectl get pods -n kube-system