这里写目录标题
一:Kubernetes详细教程
1. Kubernetes介绍
1.1 应用部署方式演变
在部署应用程序的方式上,主要经历了三个时代:
传统部署:互联网早期,会直接将应用程序部署在物理机上
优点:简单,不需要其它技术的参与
缺点:不能为应用程序定义资源使用边界,很难合理地分配计算资源,而且程序之间容易产生影响
虚拟化部署:可以在一台物理机上运行多个虚拟机,每个虚拟机都是独立的一个环境
优点:程序环境不会相互产生影响,提供了一定程度的安全性
缺点:增加了操作系统,浪费了部分资源
容器化部署:与虚拟化类似,但是共享了操作系统
优点:
可以保证每个容器拥有自己的文件系统、CPU、内存、进程空间等
运行应用程序所需要的资源都被容器包装,并和底层基础架构解耦
容器化的应用程序可以跨云服务商、跨Linux操作系统发行版进行部署
容器化部署方式给带来很多的便利,但是也会出现一些问题,比如说:
- 一个容器故障停机了,怎么样让另外一个容器立刻启动去替补停机的容器
- 当并发访问量变大的时候,怎么样做到横向扩展容器数量
这些容器管理的问题统称为容器编排问题,为了解决这些容器编排问题,就产生了一些容器编排的软件:
- Swarm:Docker自己的容器编排工具
- Mesos:Apache的一个资源统一管控的工具,需要和Marathon结合使用
- Kubernetes:Google开源的的容器编排工具
1.2 kubernetes简介
kubernetes,是一个全新的基于容器技术的分布式架构领先方案,是谷歌严格保密十几年的秘密武器----Borg系统的一个开源版本,于2014年9月发布第一个版本,2015年7月发布第一个正式版本。
kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:
- 自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器
- 弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
- 服务发现:服务可以通过自动发现的形式找到它所依赖的服务
- 负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
- 版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
- 存储编排:可以根据容器自身的需求自动创建存储卷
1.3 kubernetes组件
一个kubernetes集群主要是由控制节点(master)、**工作节点(node)**构成,每个节点上都会安装不同的组件。
master:集群的控制平面,负责集群的决策 ( 管理 )
ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制
Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上
ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等
Etcd :负责存储集群中各种资源对象的信息
node:集群的数据平面,负责为容器提供运行环境 ( 干活 )
Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器
KubeProxy : 负责提供集群内部的服务发现和负载均衡
Docker : 负责节点上容器的各种操作
下面,以部署一个nginx服务来说明kubernetes系统各个组件调用关系:
-
首先要明确,一旦kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中
-
一个nginx服务的安装请求会首先被发送到master节点的apiServer组件
-
apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上
在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer -
apiServer调用controller-manager去调度Node节点安装nginx服务
-
kubelet接收到指令后,会通知docker,然后由docker来启动一个nginx的pod
pod是kubernetes的最小操作单元,容器必须跑在pod中至此, -
一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理
这样,外界用户就可以访问集群中的nginx服务了
1.4 kubernetes概念
Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控
Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行
Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器
Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等
Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod
Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签
NameSpace:命名空间,用来隔离pod的运行环境
二:k8s的项目部署
1 容器交付流程
1.1 开发阶段编写代码。
测试。编写Dockerfile。
1.2 持续集成
- 代码编译、打包。
- 制作镜像。
- 将镜像上传到镜像仓库。
1.3 应用部署环境准备。
创建Pod、Service、Ingress。
1.4 运维监控。
- 故障排查。
- 应用升级及优化。……
2 k8s中部署Java项目的流程
① 通过Dockerfile制作镜像。
② 将镜像推送到镜像仓库,比如阿里云镜像仓库等。
③ Pod控制器部署镜像。
④ 创建Service或Ingress对外暴露应用。
⑤ 对集群进行监控、升级等。
3 k8s中部署Java项目
3.1 前提说明
本人是在Windows进行开发的,部署在Linux(CentOS7)中的k8集群。
3.2 准备Java项目,并将项目进行打包
3.2.1 概述
准备一个Java项目,将Java项目进行打包,本次使用SpringBoot项目为例,使用的JDK的版本是11。
3.2.2 准备工作JDK 11 。Maven 3.6x。
3.2.3 演示的SpringBoot项目
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>springboot2</artifactId>
<version>1.0</version>
<name>springboot2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
HelloController.java
</project>HelloController.javapackage com.example.springboot2.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author 许大仙
* @version 1.0
* @since 2021-01-12 09:18
*/
@RestController
public class HelloController {
@RequestMapping(value = "/hello")
public String hello() {
return "hello";
}
}
启动类:package com.example.springboot2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Springboot2Application {
public static void main(String[] args) {
SpringApplication.run(Springboot2Application.class, args);
}
}
3.2.4 使用Maven进行打包
打包命令:mvn clean install
3.2.5 在项目的根目录下新建Dockerfile文件
Dockerfile:
FROM openjdk
VOLUME /tmp
COPY ./target/springboot2-1.0.jar springboot2-1.0.jar
RUN bash -c "touch /springboot2-1.0.jar"
# 声明时区
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
#声明运行时容器提供服务端口,这只是一个声明,在运行时并不会因为这个声明应用就会开启这个端口的服务
EXPOSE 8080
ENTRYPOINT ["java","-jar","/springboot2-1.0.jar"]
3.3 制作镜像
- 将整个项目通过ftp上传到k8s集群所在的服务器中(其实完全可以只上传jar包和Dockerfile文件)。
- 进入springboot2目录:
cd springboot2
- 使用docker build构建镜像:
springboot是镜像的名称
docker build -t springboot2 .
3.4 推送镜像
阿里云创建命名空间:
-
阿里云创建镜像仓库:
-
-
登录阿里云
Docker Registry:sudo docker login --username=阿里云账号 registry.cn-hangzhou.aliyuncs.com
- 查看上传的Docker镜像的id:
docker images
- 给镜像打tag:
sudo docker tag bc56e4a83ff7 registry.cn-hangzhou.aliyuncs.com/k8s-test-123/springboot2:latest
- 推送镜像:
sudo docker push registry.cn-hangzhou.aliyuncs.com/k8s-test-123/springboot2:latest
3.5 部署镜像暴露应用
-创建deployment.yaml文件,内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: springboot2
name: springboot2
spec:
replicas: 3
selector:
matchLabels:
app: springboot2
template:
metadata:
labels:
app: springboot2
spec:
containers:
- image: registry.cn-hangzhou.aliyuncs.com/k8s-test-123/springboot2:latest
name: springboot2
- 创建Deployment:
kubectl create -f deployment.yaml
- 查看Deployment和Pod:
kubectl get deploy,pod
- 创建service.yaml文件,内容如下:
apiVersion: v1
kind: Service
metadata:
labels:
app: springboot2
name: svc
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
nodePort: 30091
selector:
app: springboot2
type: NodePort
- 创建Service:
kubectl create -f service.yaml
- 查看Service:
kubectl get service
三:kubeadm安装高可用k8s集群
电脑内存最好32G以上。
1 高可用集群规划图
2 主机规划
3 环境搭建
3.1 前言本次搭建的环境需要五台CentOS服务器(三主二从),然后在每台服务器中分别安装Docker、kubeadm和kubectl以及kubelet。
没有特殊说明,就是所有机器都需要执行。
3.2 环境初始化
3.2.1 检查操作系统的版本
- 检查操作系统的版本(要求操作系统的版本至少在7.5以上):
cat /etc/redhat-release
3.2.2 关闭防火墙并禁止防火墙开机启动
- 关闭防火墙:
systemctl stop firewalld
- 禁止防火墙开机启动:
systemctl disable firewalld
3.2.3 设置主机名
- 设置主机名:
hostnamectl set-hostname
- 设置192.168.18.100的主机名:
hostnamectl set-hostname k8s-master01
- 设置192.168.18.101的主机名:
hostnamectl set-hostname k8s-master02
- 设置192.168.18.102的主机名:
hostnamectl set-hostname k8s-master03
- 设置192.168.18.103的主机名:
hostnamectl set-hostname k8s-node01
- 设置192.168.18.104的主机名:
hostnamectl set-hostname k8s-node023.2.4
3.2.4 主机名解析
为了方便后面集群节点间的直接调用,需要配置一下主机名解析,企业中推荐使用内部的DNS服务器。
cat >> /etc/hosts << EOF
192.168.18.100 k8s-master01
192.168.18.101 k8s-master02
192.168.18.102 k8s-master03
192.168.18.103 k8s-node01
192.168.18.104 k8s-node02
192.168.18.110 k8s-master-lb # VIP(虚拟IP)用于LoadBalance,如果不是高可用集群,该IP可以是k8s-master01的IP EOF3.2.5
3.2.5 时间同步
kubernetes要求集群中的节点时间必须精确一致,所以在每个节点上添加时间同步:
yum install ntpdate -y
ntpdate time.windows.com
3.2.6 关闭selinux
- 查看selinux是否开启:
getenforce
- 永久关闭selinux,需要重启:
sed -i ‘s/enforcing/disabled/’ /etc/selinux/config
临时关闭selinux,重启之后,无效:
setenforce 0
3.2.7 关闭swap分区
- 永久关闭swap分区,需要重启:
sed -ri ‘s/.swap./#&/’ /etc/fstab
-临时关闭swap分区,重启之后,无效::
swapoff -a
3.2.8 将桥接的IPv4流量传递到iptables的链
- 在每个节点上将桥接的IPv4流量传递到iptables的链:
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
vm.swappiness = 0
EOF
加载br_netfilter模块
modprobe br_netfilter查看是否加载
lsmod | grep br_netfilter
生效
sysctl --system
3.2.9开启ipvs
- 在kubernetes中service有两种代理模型,一种是基于iptables,另一种是基于ipvs的。ipvs的性能要高于iptables的,但是如果要使用它,需要手动载入ipvs模块。
- 在每个节点安装ipset和ipvsadm:
yum -y install ipset ipvsadm
在所有节点执行如下脚本:
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 -e nf_conntrack_ipv4
- 检查是否加载:
lsmod | grep -e ipvs -e nf_conntrack_ipv4
3.2.10 所有节点配置limit
- 临时生效:
ulimit -SHn 65536
- 永久生效:
vim /etc/security/limits.conf
末尾追加如下的内容
- soft nofile 65536
- hard nofile 65536
- soft nproc 4096
- hard nproc 4096
- soft memlock unlimited
- soft memlock unlimited
3.2.11 在k8s-master01节点设置免密钥登录到其他节点
- 在k8s-master01节点生成配置文件和整数,并传输到其他节点上。
遇到输入,直接Enter即可
ssh-keygen -t rsa for i in k8s-master01 k8s-master02 k8s-master03 k8s-node01 k8s-node02;do ssh-copy-id -i .ssh/id_rsa.pub $i;done
3.2.12 所有节点升级系统并重启
所有节点升级系统并重启,此处没有升级内核:
yum -y --exclude=kernel* update && reboot
3.3 内核配置
3.3.1 查看默认的内核
- 查看默认的内核:
uname -r
3.3.2 升级内核配置
- CentOS7需要升级内核到4.18+。
- 在 CentOS 7 上启用 ELRepo 仓库:
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org rpm -Uvh
http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
- 仓库启用后,你可以使用下面的命令列出可用的内核相关包:
yum --disablerepo="*" --enablerepo=“elrepo-kernel” list available
- 安装最新的主线稳定内核:
yum -y --enablerepo=elrepo-kernel install kernel-ml
- 设置 GRUB 默认的内核版本:
vim /etc/default/grub
修改部分, GRUB 初始化页面的第一个内核将作为默认内核
GRUB_DEFAULT=0
重新创建内核配置
grub2-mkconfig -o /boot/grub2/grub.cfg
- 重启机器应用最新内核:
reboot
-查看最新内核版本:
uname -sr
3.4 每个节点安装Docker、kubeadm、kubelete和kubectl
3.4.1 安装Docker
- 安装Docker:
wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce.repo
yum -y install docker-ce-20.10.2
systemctl enable docker && systemctl start
dockerdocker version
- 设置Docker镜像加速器:
sudo mkdir -p /etc/dockersudo tee /etc/docker/daemon.json <<-'EOF'
{
"exec-opts": ["native.cgroupdriver=systemd"],
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
"live-restore": true,
"log-driver":"json-file",
"log-opts": {"max-size":"500m", "max-file":"3"}
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
3.4.2 添加阿里云的YUM软件源
- 由于kubernetes的镜像源在国外,非常慢,这里切换成国内的阿里云镜像源:
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
3.4.3 安装kubeadm、kubelet和kubectl
- 查看kubeadm的版本:
yum list kubeadm.x86_64 --showduplicates | sort -r
- 由于版本更新频繁,这里指定版本号部署:
yum install -y kubelet-1.20.2 kubeadm-1.20.2 kubectl-1.20.2
- 为了实现Docker使用的cgroup drvier和kubelet使用的cgroup drver一致,建议修改"/etc/sysconfig/kubelet"文件的内容:
vim /etc/sysconfig/kubelet
修改
KUBELET_EXTRA_ARGS="–cgroup-driver=systemd"
KUBE_PROXY_MODE=“ipvs”
- 所有的节点设置为开机自启动即可,由于没有生成配置文件,集群初始化后会自动启动:
systemctl enable kubelet
3.5 高可用组件安装注意:
如果不是高可用集群,haproxy和keepalived无需安装。
- k8s-master01、k8s-master02、k8s-master03节点通过yum安装HAProxy和keepAlived。
yum -y install keepalived haproxy
- k8s-master01、k8s-master02、k8s-master03节点配置HAProxy:
mkdir -pv /etc/haproxy
vim /etc/haproxy/haproxy.cfgglobal
maxconn 2000
ulimit-n 16384
log 127.0.0.1 local0 err
stats timeout 30s
defaults
log global
mode http
option httplog
timeout connect 5000
timeout client 50000
timeout server 50000
timeout http-request 15s
timeout http-keep-alive 15s
frontend monitor-in
bind *:33305
mode http
option httplog
monitor-uri /monitor
listen stats
bind *:8006
mode http
stats enable
stats hide-version
stats uri /stats
stats refresh 30s
stats realm Haproxy\ Statistics
stats auth admin:admin
frontend k8s-master
bind 0.0.0.0:16443
bind 127.0.0.1:16443
mode tcp
option tcplog
tcp-request inspect-delay 5s
default_backend k8s-master
backend k8s-master
mode tcp
option tcplog
option tcp-check
balance roundrobin
default-server inter 10s downinter 5s rise 2 fall 2 slowstart 60s maxconn 250 maxqueue 256 weight 100
# 下面的配置根据实际情况修改
server k8s-master01 192.168.18.100:6443 check
server k8s-master02 192.168.18.101:6443 check
server k8s-master03 192.168.18.102:6443 check
- k8s-master01配置Keepalived:
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
## 标识本节点的字条串,通常为 hostname
router_id k8s-master01
script_user root
enable_script_security
}
## 检测脚本
## keepalived 会定时执行脚本并对脚本执行的结果进行分析,动态调整 vrrp_instance 的优先级。如果脚本执行结果为 0,并且 weight 配置的值大于 0,则优先级相应的增加。如果脚本执行结果非 0,并且 weight配置的值小于 0,则优先级相应的减少。其他情况,维持原本配置的优先级,即配置文件中 priority 对应的值。
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
# 每2秒检查一次
interval 2
# 一旦脚本执行成功,权重减少5
weight -5
fall 3
rise 2
}
## 定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称
vrrp_instance VI_1 {
## 主节点为 MASTER,对应的备份节点为 BACKUP
state MASTER
## 绑定虚拟 IP 的网络接口,与本机 IP 地址所在的网络接口相同
interface ens33
# 主机的IP地址
mcast_src_ip 192.168.18.100
# 虚拟路由id
virtual_router_id 100
## 节点优先级,值范围 0-254,MASTER 要比 BACKUP 高
priority 100
## 优先级高的设置 nopreempt 解决异常恢复后再次抢占的问题
nopreempt
## 组播信息发送间隔,所有节点设置必须一样,默认 1s
advert_int 2
## 设置验证信息,所有节点必须一致
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
## 虚拟 IP 池, 所有节点设置必须一样
virtual_ipaddress {
## 虚拟 ip,可以定义多个
192.168.18.110
}
track_script {
chk_apiserver
}
}k8s-master02配置Keepalived:vim /etc/keepalived/keepalived.conf! Configuration File for keepalived
global_defs {
router_id k8s-master02
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 2
weight -5
fall 3
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
mcast_src_ip 192.168.18.101
virtual_router_id 101
priority 99
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
192.168.18.110
}
track_script {
chk_apiserver
}
}
- k8s-master02配置Keepalived:
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id k8s-master03
script_user root
enable_script_security
}
vrrp_script chk_apiserver {
script "/etc/keepalived/check_apiserver.sh"
interval 2
weight -5
fall 3
rise 2
}
vrrp_instance VI_1 {
state BACKUP
interface ens33
mcast_src_ip 192.168.18.102
virtual_router_id 102
priority 98
advert_int 2
authentication {
auth_type PASS
auth_pass K8SHA_KA_AUTH
}
virtual_ipaddress {
192.168.18.110
}
track_script {
chk_apiserver
}
}
- 在k8s-master01、k8s-master02、k8s-master03上新建监控脚本,并设置权限:
vim /etc/keepalived/check_apiserver.sh
#!/bin/bash
err=0
for k in $(seq 1 5)
do
check_code=$(pgrep kube-apiserver)
if [[ $check_code == "" ]]; then
err=$(expr $err + 1)
sleep 5
continue
else
err=0
break
fi
done
if [[ $err != "0" ]]; then
echo "systemctl stop keepalived"
/usr/bin/systemctl stop keepalived
exit 1
else
exit 0
fi
chmod +x /etc/keepalived/check_apiserver.sh
在k8s-master01、k8s-master02、k8s-master03上启动haproxy和keepalived:
systemctl daemon-reload
systemctl enable --now haproxy
systemctl enable --now keepalived
- 测试VIP(虚拟IP):
ping 192.168.18.110 -c 4
3.6 部署k8s的Master节点
3.6.1 yaml配置文件的方式部署k8s的Master节点
- 在k8s-master01创建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.18.100 # 本机IP
bindPort: 6443
nodeRegistration:
criSocket: /var/run/dockershim.sock
name: k8s-master01 # 本主机名
taints:
- effect: NoSchedule
key: node-role.kubernetes.io/master
---
apiServer:
timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controlPlaneEndpoint: "192.168.18.110:16443" # 虚拟IP和haproxy端口
controllerManager: {}
dns:
type: CoreDNS
etcd:
local:
dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers # 镜像仓库源
kind: ClusterConfiguration
kubernetesVersion: v1.20.2 # k8s版本
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
- 可以使用如下的命令更新kubeadm-config.yaml文件,需要将k8s设置到对应的版本:
kubeadm config migrate --old-config kubeadm-config.yaml --new-config “new.yaml”
- 将new.yaml文件复制到所有的master节点
scp new.yaml k8s-master02:/root/new.yaml
scp new.yaml k8s-master03:/root/new.yaml
- 所有的master节点提前下载镜像,可以节省初始化时间:
kubeadm config images pull --config /root/new.yaml
- k8s-master01节点初始化后,会在/etc/kubernetes目录下生成对应的证书和配置文件,之后其他的Master节点加入到k8s-master01节点即可。
kubeadm init --config /root/new.yaml --upload-certs
- 如果初始化失败,重置后再次初始化,命令如下:
kubeadm reset -f;ipvsadm --clear;rm -rf ~/.kube
- 初始化成功后,会产生token值,用于其他节点加入时使用,
Your Kubernetes control-plane 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
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
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 the control-plane node running the following command on each as root:
kubeadm join 192.168.18.110:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:505e373bae6123fc3e27e778c5fedbccbf0f91a51efdcc11b32c4573605b8e71 \
--control-plane --certificate-key 70aef5f76111a5824085c644b3f34cf830efad00c1b16b878701166bf069664e
Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
"kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.18.110:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:505e373bae6123fc3e27e778c5fedbccbf0f91a51efdcc11b32c4573605b8e71
- k8s-master01节点配置环境变量,用于访问kubernetes集群:
如果是root用户:
cat > /root/.bashrc <<EOF
export KUBECONFIG=/etc/kubernetes/admin.conf
EOF
source ~/.bash_profile
- 如果是普通用户:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- k8s-master01中查看节点的状态:
kubectl get nodes
- 采用初始化安装方式,所有的系统组件均以容器的方式运行并且在kube-system命名空间内,此时可以在k8s-master01节点查看Pod的状态:
kubectl get pod -n kube-system -o wide
3.6.2 命令行的方式部署k8s的Master节点
- 在k8s-master01、k8s-master02以及k8s-master03节点输入如下的命令:
kubeadm config images pull --kubernetes-version=v1.20.2 --image-repository=registry.aliyuncs.com/google_containers
- 在k8s-master01节点输入如下的命令:
kubeadm init \
--apiserver-advertise-address=192.168.18.100 \
--image-repository registry.aliyuncs.com/google_containers \
--control-plane-endpoint=192.168.18.110:16443 \
--kubernetes-version v1.20.2 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16 \
--upload-certs
3.7 高可用
- Master将k8s-master02节点加入到集群中:
kubeadm join 192.168.18.110:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:505e373bae6123fc3e27e778c5fedbccbf0f91a51efdcc11b32c4573605b8e71 \
--control-plane --certificate-key 70aef5f76111a5824085c644b3f34cf830efad00c1b16b878701166bf069664e
# 防止不能在此节点中不能使用kubectl命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 将k8s-master03节点加入到集群中:
kubeadm join 192.168.18.110:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:505e373bae6123fc3e27e778c5fedbccbf0f91a51efdcc11b32c4573605b8e71 \
--control-plane --certificate-key 70aef5f76111a5824085c644b3f34cf830efad00c1b16b878701166bf069664e
# 防止不能在此节点中不能使用kubectl命令
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
- 如果token过期了,需要生成新的token(在k8s-master01节点):
kubeadm token create --print-join-command
- Master节点如果要加入到集群中,需要生成–certificate-key(在k8s-master01节点):
kubeadm init phase upload-certs --upload-certs
- 然后将其他Master节点加入到集群中:
# 需要做对应的修改
kubeadm join 192.168.18.110:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:505e373bae6123fc3e27e778c5fedbccbf0f91a51efdcc11b32c4573605b8e71 \
--control-plane --certificate-key 70aef5f76111a5824085c644b3f34cf830efad00c1b16b878701166bf069664e
3.8 Node 节点的配置
- 将k8s-node1加入到集群中:
kubeadm join 192.168.18.110:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:505e373bae6123fc3e27e778c5fedbccbf0f91a51efdcc11b32c4573605b8e71
- 将k8s-node2加入到集群中:
kubeadm join 192.168.18.110:16443 --token abcdef.0123456789abcdef \
--discovery-token-ca-cert-hash sha256:505e373bae6123fc3e27e778c5fedbccbf0f91a51efdcc11b32c4573605b8e71
3.9 部署CNI网络插件
- 根据提示,在Master节点上使用kubectl工具查看节点状态:
kubectl get node
- kubernetes支持多种网络插件,比如flannel、calico、canal等,任选一种即可,本次选择flannel。
- 在所有Master节点上获取flannel配置文件(可能会失败,如果失败,请下载到本地,然后安装,如果网速不行,请点这里📎kube-flannel.yml,当然,你也可以安装calico,请点这里📎calico.yaml,推荐安装calico):
wget https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
- 在所有Master节点使用配置文件启动flannel:
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
- 在所有Master节点查看部署CNI网络插件进度:
kubectl get pods -n kube-system
- 在所有Master节点再次使用kubectl工具查看节点状态:
kubectl get nodes
- 在所有Master节点查看集群健康状况:
kubectl get cs
- 发现集群不健康,那么需要注释掉etc/kubernetes/manifests下的kube-controller-manager.yaml和kube-scheduler.yaml的–port=0:
vim /etc/kubernetes/manifests/kube-controller-manager.yaml
spec:
containers:
- command:
- kube-controller-manager
- --allocate-node-cidrs=true
- --authentication-kubeconfig=/etc/kubernetes/controller-manager.conf
- --authorization-kubeconfig=/etc/kubernetes/controller-manager.conf
- --bind-address=127.0.0.1
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --cluster-cidr=10.244.0.0/16
- --cluster-name=kubernetes
- --cluster-signing-cert-file=/etc/kubernetes/pki/ca.crt
- --cluster-signing-key-file=/etc/kubernetes/pki/ca.key
- --controllers=*,bootstrapsigner,tokencleaner
- --kubeconfig=/etc/kubernetes/controller-manager.conf
- --leader-elect=true
# 修改部分
# - --port=0
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --root-ca-file=/etc/kubernetes/pki/ca.crt
- --service-account-private-key-file=/etc/kubernetes/pki/sa.key
- --service-cluster-ip-range=10.96.0.0/12
- --use-service-account-credentials=true
vim /etc/kubernetes/manifests/kube-scheduler.yaml
spec:
containers:
- command:
- kube-scheduler
- --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
- --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
- --bind-address=127.0.0.1
- --kubeconfig=/etc/kubernetes/scheduler.conf
- --leader-elect=true
# 修改部分
# - --port=0
- 在所有Master节点再次查看集群健康状况:
kubectl get cs