kubernetes(k8s)介绍安装和部署实战

2023-05-16

kubernetes 基本介绍

kubernetes,简称 K8s,是用 8 代替 8 个字符“ubernete”而成的缩写。是一个开源
的,用于管理云平台中多个主机上的容器化的应用,Kubernetes 的目标是让部署容器化的
应用简单并且高效(powerful),Kubernetes 提供了应用部署,规划,更新,维护的一种
机制。
传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配
置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等
操作,当然也可以通过创建虚拟机的方式来实现某些功能,但是虚拟机非常重,并不利于
可移植性。
新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件
系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,
由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进
行迁移。
容器占用资源少、部署快,每个应用可以被打包成一个容器镜像,每个应用与容器间
成一对一关系也使容器有更大优势,使用容器可以在 build 或 release 的阶段,为应用创
建容器镜像,因为每个应用不需要与其余的应用堆栈组合,也不依赖于生产环境基础结构,
这使得从研发到测试、生产能提供一致环境。类似地,容器比虚拟机轻量、更“透明”,
这更便于监控和管理。
Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、
应用容器化管理。在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以便
对应用请求进行负载均衡。
在 Kubernetes 中,我们可以创建多个容器,每个容器里面运行一个应用实例,然后通
过内置的负载均衡策略,实现对这一组应用实例的管理、发现、访问,而这些细节都不需
要运维人员去进行复杂的手工配置和处理

kubernetes 功能和架构

概述

Kubernetes 是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务。通过
Kubernetes 能够进行应用的自动化部署和扩缩容。在 Kubernetes 中,会将组成应用的容
器组合成一个逻辑单元以更易管理和发现。Kubernetes 积累了作为 Google 生产环境运行
工作负载 15 年的经验,并吸收了来自于社区的最佳想法和实践。

K8s 功能:

(1)自动装箱
基于容器对应用运行环境的资源配置要求自动部署应用容器
(2)自我修复(自愈能力)
当容器失败时,会对容器进行重启
当所部署的 Node 节点有问题时,会对容器进行重新部署和重新调度
当容器未通过监控检查时,会关闭此容器直到容器正常运行时,才会对外提供服务
(3)水平扩展
通过简单的命令、用户 UI 界面或基于 CPU 等资源使用情况,对应用容器进行规模扩大
或规模剪裁
(3)服务发现
用户不需使用额外的服务发现机制,就能够基于 Kubernetes 自身能力实现服务发现和
负载均衡
(4)滚动更新
可以根据应用的变化,对应用容器运行的应用,进行一次性或批量式更新
(5)版本回退
可以根据应用部署情况,对应用容器运行的应用,进行历史版本即时回退
(6)密钥和配置管理
在不需要重新构建镜像的情况下,可以部署和更新密钥和应用配置,类似热部署。
(7)存储编排
自动实现存储系统挂载及应用,特别对有状态应用实现数据持久化非常重要
存储系统可以来自于本地目录、网络存储(NFS、Gluster、Ceph 等)、公共云存储服务
(8)批处理
提供一次性任务,定时任务;满足批量数据处理和分析的场景

应用部署架构分类

(1) 无中心节点架构
GlusterFS
(2) 有中心节点架构
HDFS
K8S

k8s 集群架构

在这里插入图片描述

k8s 集群架构节点角色功能

Master Node
k8s 集群控制节点, 对集群进行调度管理, 接受集群外用户去集群操作请求;
Master Node 由 API Server、 Scheduler、 ClusterState Store( ETCD 数据库) 和
Controller MangerServer 所组成
Worker Node
集群工作节点, 运行用户业务应用容器;
Worker Node 包含 kubelet、 kube proxy 和 ContainerRuntime;
在这里插入图片描述

kubernetes 集群搭建(kubeadm 方式)

1、 前置知识点

目前生产部署 Kubernetes 集群主要有两种方式:
(1) kubeadm
Kubeadm 是一个 K8s 部署工具, 提供 kubeadm init 和 kubeadm join, 用于快速部
署 Kubernetes 集群。
官方地址: https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm/
(2) 二进制包
从 github 下载发行版的二进制包, 手动部署每个组件, 组成 Kubernetes 集群。
Kubeadm 降低部署门槛, 但屏蔽了很多细节, 遇到问题很难排查。 如果想更容易可
控, 推荐使用二进制包部署 Kubernetes 集群, 虽然手动部署麻烦点, 期间可以学习很
多工作原理, 也利于后期维护。

2、 kubeadm 部署方式介绍

kubeadm 是官方社区推出的一个用于快速部署 kubernetes 集群的工具, 这个工具能通
过两条指令完成一个 kubernetes 集群的部署:
第一、 创建一个 Master 节点 kubeadm init
第二, 将 Node 节点加入到当前集群中 $ kubeadm join <Master 节点的 IP 和端口 >

3、 安装要求

在开始之前, 部署 Kubernetes 集群机器需要满足以下几个条件:- 一台或多台机器, 操作系统 CentOS7.x-86_x64

  • 硬件配置: 2GB 或更多 RAM, 2 个 CPU 或更多 CPU, 硬盘 30GB 或更多
  • 集群中所有机器之间网络互通
  • 可以访问外网, 需要拉取镜像
  • 禁止 swap 分区

4、 最终目标

( 1) 在所有节点上安装 Docker 和 kubeadm
( 2) 部署 Kubernetes Master
( 3) 部署容器网络插件
( 4) 部署 Kubernetes Node, 将节点加入 Kubernetes 集群中
( 5) 部署 Dashboard Web 页面, 可视化查看 Kubernetes 资源

5、 准备环境

在这里插入图片描述角色 IP
k8s-master 192.168.31.61
k8s-node1 192.168.31.62
k8s-node2 192.168.31.63

6、 系统初始化

6.1 关闭防火墙:

$ systemctl stop firewalld
$ systemctl disable firewalld

6.2 关闭 selinux:

$ sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
$ setenforce 0 # 临时

6.3 关闭 swap:

$ swapoff -a # 临时
$ vim /etc/fstab # 永久

6.4 主机名:

$ hostnamectl set-hostname

6.5 在 master 添加 hosts:

$ cat >> /etc/hosts << EOF
192.168.31.61 k8s-master
192.168.31.62 k8s-node1
192.168.31.63 k8s-node2
EOF

6.6 将桥接的 IPv4 流量传递到 iptables 的链:

$ cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1net.bridge.bridge-nf-call-iptables = 1
EOF
$ sysctl --system # 生效

6.7 时间同步:

$ yum install ntpdate -y
$ ntpdate time.windows.com

7、 所有节点安装 Docker/kubeadm/kubelet

Kubernetes 默认 CRI( 容器运行时) 为 Docker, 因此先安装 Docker。

( 1) 安装 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-18.06.1.ce-3.el7
$ systemctl enable docker && systemctl start docker
$ docker --version

( 2) 添加阿里云 YUM 软件源

设置仓库地址

$ cat > /etc/docker/daemon.json << EOF
{
"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
}
EOF

添加 yum 源

$ cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetesbaseurl=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) 安装 kubeadm, kubelet 和 kubectl

$ yum install -y kubelet kubeadm kubectl
$ systemctl enable kubelet

8、 部署 Kubernetes Master

( 1) 在 192.168.31.61( Master) 执行

$ kubeadm init \
--apiserver-advertise-address=192.168.31.61 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.17.0 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.244.0.0/16

由于默认拉取镜像地址 k8s.gcr.io 国内无法访问, 这里指定阿里云镜像仓库地址。

( 2) 使用 kubectl 工具:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
$ kubectl get nodes

9、 安装 Pod 网络插件( CNI)

$ kubectl apply – f
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kubeflannel.yml

确保能够访问到 quay.io 这个 registery。 如果 Pod 镜像下载失败, 可以改这个镜像地址

10、 加入 Kubernetes Node

( 1) 在 192.168.31.62/63( Node) 执行
向集群添加新节点, 执行在 kubeadm init 输出的 kubeadm join 命令:

$ kubeadm join 192.168.31.61:6443 --token esce21.q6hetwm8si29qxwn \
--discovery-token-ca-cert-hash
sha256:00603a05805807501d7181c3d60b478788408cfe6cedefedb1f97569708be9c5

11、 测试 kubernetes 集群

在 Kubernetes 集群中创建一个 pod, 验证是否正常运行:

$ kubectl create deployment nginx --image=nginx
$ kubectl expose deployment nginx --port=80 --type=NodePort
$ kubectl get pod,svc

访问地址: http://NodeIP:Port

kubernetes 集群搭建(二进制方式)

1、 安装要求

在开始之前, 部署 Kubernetes 集群机器需要满足以下几个条件:
( 1) 一台或多台机器, 操作系统 CentOS7.x-86_x64
( 2) 硬件配置: 2GB 或更多 RAM, 2 个 CPU 或更多 CPU, 硬盘 30GB 或更多
( 3) 集群中所有机器之间网络互通
( 4) 可以访问外网, 需要拉取镜像, 如果服务器不能上网, 需要提前下载镜像并导入节点
( 5) 禁止 swap 分区

2、 准备环境

( 1) 软件环境:

软件版本
操作系统CentOS7.8_x64 ( mini)
Docker19-ce
Kubernetes1.19

( 2)服务器规划:

角色IP组件
k8s-master192.168.31.71kube-apiserver, kube-controller-manager, kube-scheduler, etcd
k8s-node1192.168.31.72kubelet, kube-proxy, docker, etcd
k8s-node2192.168.31.73kubelet, kube-proxy, docker, etcd

3、 操作系统初始化配

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭 selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
setenforce 0 # 临时
# 关闭 swap
swapoff -a # 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab # 永久

# 根据规划设置主机名
hostnamectl set-hostname <hostname># 在 master 添加 hosts
cat >> /etc/hosts << EOF
192.168.44.147 m1
192.168.44.148 n1
EOF

# 将桥接的 IPv4 流量传递到 iptables 的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system # 生效

# 时间同步
yum install ntpdate -y
ntpdate time.windows.com

4、 部署 Etcd 集群

Etcd 是一个分布式键值存储系统, Kubernetes 使用 Etcd 进行数据存储, 所以先准备
一个 Etcd 数据库, 为解决 Etcd 单点故障, 应采用集群方式部署, 这里使用 3 台组建集
群, 可容忍 1 台机器故障, 当然, 你也可以使用 5 台组建集群, 可容忍 2 台机器故障。

节点名称IP
etcd-1192.168.31.71
etcd-2192.168.31.72
etcd-3192.168.31.73
注: 为了节省机器, 这里与 K8s 节点机器复用。 也可以独立于 k8s 集群之外部署, 只要
apiserver 能连接到就行。

4.1 准备 cfssl 证书生成工具

cfssl 是一个开源的证书管理工具, 使用 json 文件生成证书, 相比 openssl 更方便使用。
找任意一台服务器操作, 这里用 Master 节点。

wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
mv cfssl_linux-amd64 /usr/local/bin/cfssl
mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo

4.2 生成 Etcd 证书

( 1) 自签证书颁发机构( CA)

创建工作目录:

mkdir -p ~/TLS/{etcd,k8s}
cd TLS/etcd

自签 CA:

cat > ca-config.json<< EOF
{
	"signing": {
		"default": {
			"expiry": "87600h"
		},
		"profiles": {
		"www": {
			"expiry": "87600h",
			"usages": [
				"signing","key encipherment",
				"server auth",
				"client auth"
			]
			}
		}
	}
} 
EOF
cat > ca-csr.json<< EOF
{
	"CN": "etcd CA",
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [
		{
		"C": "CN",
		"L": "Beijing",
		"ST": "Beijing"
		}
	]
} 
EOF

生成证书:

cfssl gencert -initca ca-csr.json | cfssljson -bare ca -ls *pem
ca-key.pem ca.pem

( 2) 使用自签 CA 签发 Etcd HTTPS 证书

创建证书申请文件:

cat > server-csr.json<< EOF
{
	"CN": "etcd",
	"hosts": [
		"192.168.31.71",
		"192.168.31.72",
		"192.168.31.73"
	],
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [
		{
		"C": "CN",
		"L": "BeiJing",
		"ST": "BeiJing"
		}
	]
} 
EOF

注: 上述文件 hosts 字段中 IP 为所有 etcd 节点的集群内部通信 IP, 一个都不能少! 为了
方便后期扩容可以多写几个预留的 IP。
生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -
profile=www server-csr.json | cfssljson -bare server
ls server*pem
server-key.pem server.pem

4.3 从 Github 下载二进制文件

下载地址: https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-
linux-amd64.tar.gz

4.4 部署 Etcd 集群

以下在节点 1 上操作, 为简化操作, 待会将节点 1 生成的所有文件拷贝到节点 2 和节点 3.

( 1) 创建工作目录并解压二进制包

mkdir /opt/etcd/{bin,cfg,ssl} – p
tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/

( 2) 创建 etcd 配置文件

cat > /opt/etcd/cfg/etcd.conf << EOF
#[Member]
ETCD_NAME="etcd-1"
ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.31.71:2380"
ETCD_LISTEN_CLIENT_URLS="https://192.168.31.71:2379"
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.31.71:2380"
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.31.71:2379"
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.31.71:2380,etcd-
2=https://192.168.31.72:2380,etcd-3=https://192.168.31.73:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"
EOF

ETCD_NAME: 节点名称, 集群中唯一
ETCD_DATA_DIR: 数据目录
ETCD_LISTEN_PEER_URLS: 集群通信监听地址
ETCD_LISTEN_CLIENT_URLS: 客户端访问监听地址
ETCD_INITIAL_ADVERTISE_PEER_URLS: 集群通告地址
ETCD_ADVERTISE_CLIENT_URLS: 客户端通告地址
ETCD_INITIAL_CLUSTER: 集群节点地址
ETCD_INITIAL_CLUSTER_TOKEN: 集群 Token
ETCD_INITIAL_CLUSTER_STATE: 加入集群的当前状态, new 是新集群, existing 表示加入
已有集群

( 3) systemd 管理 etcd

cat > /usr/lib/systemd/system/etcd.service << EOF
[Unit]
Description=Etcd Server
After=network.target
After=network-online.target
Wants=network-online.target
[Service]
Type=notify
EnvironmentFile=/opt/etcd/cfg/etcd.conf
ExecStart=/opt/etcd/bin/etcd \
--cert-file=/opt/etcd/ssl/server.pem \
--key-file=/opt/etcd/ssl/server-key.pem \
--peer-cert-file=/opt/etcd/ssl/server.pem \
--peer-key-file=/opt/etcd/ssl/server-key.pem \
--trusted-ca-file=/opt/etcd/ssl/ca.pem \--peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
--logger=zap
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

( 4) 拷贝刚才生成的证书

把刚才生成的证书拷贝到配置文件中的路径:

cp ~/TLS/etcd/ca*pem ~/TLS/etcd/server*pem /opt/etcd/ssl/

( 5) 启动并设置开机启动

systemctl daemon-reload
systemctl start etcd
systemctl enable etcd

( 6) 将上面节点 1 所有生成的文件拷贝到节点 2 和节点 3

scp -r /opt/etcd/ root@192.168.31.72:/opt/
scp /usr/lib/systemd/system/etcd.service
root@192.168.31.72:/usr/lib/systemd/system/
scp -r /opt/etcd/ root@192.168.31.73:/opt/
scp /usr/lib/systemd/system/etcd.service
root@192.168.31.73:/usr/lib/systemd/system/

然后在节点 2 和节点 3 分别修改 etcd.conf 配置文件中的节点名称和当前服务器 IP:

vi /opt/etcd/cfg/etcd.conf
#[Member]
ETCD_NAME="etcd-1" # 修改此处, 节点 2 改为 etcd-2, 节点 3 改为 etcd-3ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
ETCD_LISTEN_PEER_URLS="https://192.168.31.71:2380" # 修改此处为当前服务器 IP
ETCD_LISTEN_CLIENT_URLS="https://192.168.31.71:2379" # 修改此处为当前服务器 IP
#[Clustering]
ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.31.71:2380" # 修改此处为当前
服务器 IP
ETCD_ADVERTISE_CLIENT_URLS="https://192.168.31.71:2379" # 修改此处为当前服务器
IP
ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.31.71:2380,etcd-
2=https://192.168.31.72:2380,etcd-3=https://192.168.31.73:2380"
ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new"

最后启动 etcd 并设置开机启动, 同上。

( 7) 查看集群状态

ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --
cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --
endpoints="https://192.168.31.71:2379,https://192.168.31.72:2379,https://192.16
8.31.73:2379" endpoint health
https://192.168.31.71:2379 is healthy: successfully committed proposal: took =
8.154404ms
https://192.168.31.73:2379 is healthy: successfully committed proposal: took =
9.044117ms
https://192.168.31.72:2379 is healthy: successfully committed proposal: took =
10.000825ms

如果输出上面信息, 就说明集群部署成功。 如果有问题第一步先看日志:

/var/log/message 或 journalctl -u etcd

5、 安装 Docker

下载地址: https://download.docker.com/linux/static/stable/x86_64/docker-
19.03.9.tgz
以下在所有节点操作。 这里采用二进制安装, 用 yum 安装也一样。

( 1) 解压二进制包

tar zxvf docker-19.03.9.tgz
mv docker/* /usr/bin

( 2) systemd 管理 docker

cat > /usr/lib/systemd/system/docker.service << EOF
[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service
Wants=network-online.target
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
ExecReload=/bin/kill -s HUP $MAINPID
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TimeoutStartSec=0
Delegate=yes
KillMode=process
Restart=on-failure
StartLimitBurst=3
StartLimitInterval=60s
[Install]
WantedBy=multi-user.target
EOF

( 3) 创建配置文件

mkdir /etc/docker
cat > /etc/docker/daemon.json << EOF
{
	"registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"]
} 
EOF

registry-mirrors 阿里云镜像加速器

( 4) 启动并设置开机启动

systemctl daemon-reload
systemctl start docker
systemctl enable docker

6、 部署 Master Node

6.1 生成 kube-apiserver 证书

( 1) 自签证书颁发机构( CA)

cat > ca-config.json<< EOF
{
	"signing": {
		"default": {
			"expiry": "87600h"
		},
		"profiles": {
			"kubernetes": {
				"expiry": "87600h",
				"usages": [
					"signing",
					"key encipherment",
					"server auth",
					"client auth"
				]
			}
		}
	}
} 
EOF
cat > ca-csr.json<< EOF
{
	"CN": "kubernetes",
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [
		{
		"C": "CN",
		"L": "Beijing",
		"ST": "Beijing",
		"O": "k8s",
		"OU": "System"
		}
	]
} 
EOF

( 2) 生成证书:


```bash
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
ls *pem
ca-key.pem ca.pem

( 3) 使用自签 CA 签发 kube-apiserver HTTPS 证书

创建证书申请文件:

cd TLS/k8s
cat > server-csr.json<< EOF
{
	"CN": "kubernetes",
	"hosts": [
		"10.0.0.1",
		"127.0.0.1",
		"192.168.31.71",
		"192.168.31.72",
		"192.168.31.73",
		"192.168.31.74",
		"192.168.31.81",
		"192.168.31.82",
		"192.168.31.88",
		"kubernetes",
		"kubernetes.default",
		"kubernetes.default.svc",
		"kubernetes.default.svc.cluster",
		"kubernetes.default.svc.cluster.local"
	],
	"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [
		{
		"C": "CN",
		"L": "BeiJing",
		"ST": "BeiJing","O": "k8s",
		"OU": "System"
		}
	]
} 
EOF

生成证书:

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -
profile=kubernetes server-csr.json | cfssljson -bare server
ls server*pem
server-key.pem server.pem

6.2 从 Github 下载二进制文件

下载地址:
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-
1.18.md#v1183
注: 打开链接你会发现里面有很多包, 下载一个 server 包就够了, 包含了 Master 和
Worker Node 二进制文件。

6.3 解压二进制包

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
tar zxvf kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/bin
cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin
cp kubectl /usr/bin/

6.4 部署 kube-apiserver

1. 创建配置文件

cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF
KUBE_APISERVER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--etcdservers=https://192.168.31.71:2379,https://192.168.31.72:2379,https://192.168.3
1.73:2379 \\
--bind-address=192.168.31.71 \\
--secure-port=6443 \\
--advertise-address=192.168.31.71 \\
--allow-privileged=true \\
--service-cluster-ip-range=10.0.0.0/24 \\
--enable-admissionplugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestric
tion \\
--authorization-mode=RBAC,Node \\
--enable-bootstrap-token-auth=true \\
--token-auth-file=/opt/kubernetes/cfg/token.csv \\
--service-node-port-range=30000-32767 \\
--kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \\
--kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \\
--tls-cert-file=/opt/kubernetes/ssl/server.pem \\
--tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \\
--client-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--etcd-cafile=/opt/etcd/ssl/ca.pem \\
--etcd-certfile=/opt/etcd/ssl/server.pem \\
--etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
--audit-log-maxage=30 \\
--audit-log-maxbackup=3 \\
--audit-log-maxsize=100 \\
--audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
EOF

注: 上面两个\ \ 第一个是转义符, 第二个是换行符, 使用转义符是为了使用 EOF 保留换
行符。
– logtostderr: 启用日志
—v: 日志等级
– log-dir: 日志目录
– etcd-servers: etcd 集群地址
– bind-address: 监听地址
– secure-port: https 安全端口
– advertise-address: 集群通告地址
– allow-privileged: 启用授权
– service-cluster-ip-range: Service 虚拟 IP 地址段
– enable-admission-plugins: 准入控制模块
– authorization-mode: 认证授权, 启用 RBAC 授权和节点自管理
– enable-bootstrap-token-auth: 启用 TLS bootstrap 机制
– token-auth-file: bootstrap token 文件
– service-node-port-range: Service nodeport 类型默认分配端口范围
– kubelet-client-xxx: apiserver 访问 kubelet 客户端证书
– tls-xxx-file: apiserver https 证书
– etcd-xxxfile: 连接 Etcd 集群证书
– audit-log-xxx: 审计日志

2. 拷贝刚才生成的证书

把刚才生成的证书拷贝到配置文件中的路径:

cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/

3. 启用 TLS Bootstrapping 机制

TLS Bootstraping: Master apiserver 启用 TLS 认证后, Node 节点 kubelet 和 kubeproxy 要与 kube-apiserver 进行通信, 必须使用 CA 签发的有效证书才可以, 当 Node
节点很多时, 这种客户端证书颁发需要大量工作, 同样也会增加集群扩展复杂度。 为了
简化流程, Kubernetes 引入了 TLS bootstraping 机制来自动颁发客户端证书, kubelet
会以一个低权限用户自动向 apiserver 申请证书, kubelet 的证书由 apiserver 动态签署。所以强烈建议在 Node 上使用这种方式, 目前主要用于 kubelet, kube-proxy 还是由我
们统一颁发一个证书。
TLS bootstraping 工作流程:
在这里插入图片描述
创建上述配置文件中 token 文件:

cat > /opt/kubernetes/cfg/token.csv << EOF
c47ffb939f5ca36231d9e3121a252940,kubelet-bootstrap,10001,"system:nodebootstrapper"
EOF

格式: token, 用户名, UID, 用户组
token 也可自行生成替换:

head -c 16 /dev/urandom | od -An -t x | tr -d ' '

4. systemd 管理 apiserver

cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf
ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

5. 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-apiserver
systemctl enable kube-apiserver

6. 授权 kubelet-bootstrap 用户允许请求证书

kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap

6.5 部署 kube-controller-manager

1. 创建配置文件

cat > /opt/kubernetes/cfg/kube-controller-manager.conf << EOF
KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--leader-elect=true \\
--master=127.0.0.1:8080 \\
--bind-address=127.0.0.1 \\
--allocate-node-cidrs=true \\
--cluster-cidr=10.244.0.0/16 \\
--service-cluster-ip-range=10.0.0.0/24 \\
--cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
--cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--root-ca-file=/opt/kubernetes/ssl/ca.pem \\
--service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
--experimental-cluster-signing-duration=87600h0m0s"
EOF

– master: 通过本地非安全本地端口 8080 连接 apiserver。
– leader-elect: 当该组件启动多个时, 自动选举( HA)
– cluster-signing-cert-file/– cluster-signing-key-file: 自动为 kubelet 颁发证书
的 CA, 与 apiserver 保持一致

2. systemd 管理 controller-manager

cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/kubernetes/kubernetes
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-controller-manager.conf
ExecStart=/opt/kubernetes/bin/kube-controller-manager\$KUBE_CONTROLLER_MANAGER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

3. 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-controller-manager
systemctl enable kube-controller-manager

6.6 部署 kube-scheduler

1. 创建配置文件

cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF
KUBE_SCHEDULER_OPTS="--logtostderr=false \
--v=2 \
--log-dir=/opt/kubernetes/logs \
--leader-elect \
--master=127.0.0.1:8080 \
--bind-address=127.0.0.1"
EOF

– master: 通过本地非安全本地端口 8080 连接 apiserver。
– leader-elect: 当该组件启动多个时, 自动选举( HA)

2. systemd 管理 scheduler

cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf
ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
Restart=on-failure
[Install]
WantedBy=multi-user.target
EOF

3. 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-scheduler
systemctl enable kube-scheduler

4. 查看集群状态

所有组件都已经启动成功, 通过 kubectl 工具查看当前集群组件状态:

kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-2 Healthy {"health":"true"}
etcd-1 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}

如上输出说明 Master 节点组件运行正常。

7、 部署 Worker Node

下面还是在 Master Node 上操作, 即同时作为 Worker Node

7.1 创建工作目录并拷贝二进制文件

在所有 worker node 创建工作目录:

mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

从 master 节点拷贝:

cd kubernetes/server/bin
cp kubelet kube-proxy /opt/kubernetes/bin # 本地拷贝

7.2 部署 kubelet

1. 创建配置文件

cat > /opt/kubernetes/cfg/kubelet.conf << EOF
KUBELET_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--hostname-override=k8s-master \\
--network-plugin=cni \\
--kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\
--bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig \\
--config=/opt/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=lizhenliang/pause-amd64:3.0"
EOF

– hostname-override: 显示名称, 集群中唯一
– network-plugin: 启用 CNI
– kubeconfig: 空路径, 会自动生成, 后面用于连接 apiserver
– bootstrap-kubeconfig: 首次启动向 apiserver 申请证书
– config: 配置参数文件
– cert-dir: kubelet 证书生成目录
– pod-infra-container-image: 管理 Pod 网络容器的镜像

2. 配置参数文件

cat > /opt/kubernetes/cfg/kubelet-config.yml << EOF
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1address: 0.0.0.0
port: 10250
readOnlyPort: 10255
cgroupDriver: cgroupfs
clusterDNS:
- 10.0.0.2
clusterDomain: cluster.local
failSwapOn: false
authentication:
anonymous:
enabled: false
webhook:
cacheTTL: 2m0s
enabled: true
x509:
clientCAFile: /opt/kubernetes/ssl/ca.pem
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: 5m0s
cacheUnauthorizedTTL: 30s
evictionHard:
imagefs.available: 15%
memory.available: 100Mi
nodefs.available: 10%
nodefs.inodesFree: 5%
maxOpenFiles: 1000000
maxPods: 110
EOF

3. 生成 bootstrap.kubeconfig 文件

KUBE_APISERVER="https://192.168.31.71:6443" # apiserver IP:PORT
TOKEN="c47ffb939f5ca36231d9e3121a252940" # 与 token.csv 里保持一致
# 生成 kubelet bootstrap kubeconfig 配置文件

kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \
--kubeconfig=bootstrap.kubeconfig
kubectl config set-credentials "kubelet-bootstrap" \
--token=${TOKEN} \
--kubeconfig=bootstrap.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user="kubelet-bootstrap" \
--kubeconfig=bootstrap.kubeconfig
kubectl config use-context default --kubeconfig=bootstrap.kubeconfig

拷贝到配置文件路径:

cp bootstrap.kubeconfig /opt/kubernetes/cfg

4. systemd 管理 kubelet

cat > /usr/lib/systemd/system/kubelet.service << EOF
[Unit]
Description=Kubernetes Kubelet
After=docker.service
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kubelet.confExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

5. 启动并设置开机启动

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet

7.3 批准 kubelet 证书申请并加入集群

# 查看 kubelet 证书请求
kubectl get csr
NAME AGE SIGNERNAME
REQUESTOR CONDITION
node-csr-uCEGPOIiDdlLODKts8J658HrFq9CZ--K6M4G7bjhk8A 6m3s
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
# 批准申请
kubectl certificate approve node-csr-uCEGPOIiDdlLODKts8J658HrFq9CZ--
K6M4G7bjhk8A
# 查看节点
kubectl get node

注: 由于网络插件还没有部署, 节点会没有准备就绪 NotReady

7.4 部署 kube-proxy

1. 创建配置文件

cat > /opt/kubernetes/cfg/kube-proxy.conf << EOF
KUBE_PROXY_OPTS="--logtostderr=false \\
--v=2 \\
--log-dir=/opt/kubernetes/logs \\
--config=/opt/kubernetes/cfg/kube-proxy-config.yml"
EOF

2. 配置参数文件

cat > /opt/kubernetes/cfg/kube-proxy-config.yml << EOF
kind: KubeProxyConfiguration
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
metricsBindAddress: 0.0.0.0:10249
clientConnection:
kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig
hostnameOverride: k8s-master
clusterCIDR: 10.0.0.0/24
EOF

3. 生成 kube-proxy.kubeconfig 文件

生成 kube-proxy 证书:

# 切换工作目录
cd TLS/k8s
# 创建证书请求文件
cat > kube-proxy-csr.json<< EOF
{
	"CN": "system:kube-proxy",
	"hosts": [],"key": {
		"algo": "rsa",
		"size": 2048
	},
	"names": [
		{
		"C": "CN",
		"L": "BeiJing",
		"ST": "BeiJing",
		"O": "k8s",
		"OU": "System"
		}
	]
} 
EOF
# 生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -
profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
ls kube-proxy*pem
kube-proxy-key.pem kube-proxy.pem

生成 kubeconfig 文件:

KUBE_APISERVER="https://192.168.31.71:6443"
kubectl config set-cluster kubernetes \
--certificate-authority=/opt/kubernetes/ssl/ca.pem \
--embed-certs=true \
--server=${KUBE_APISERVER} \--kubeconfig=kube-proxy.kubeconfig
kubectl config set-credentials kube-proxy \
--client-certificate=./kube-proxy.pem \
--client-key=./kube-proxy-key.pem \
--embed-certs=true \
--kubeconfig=kube-proxy.kubeconfig
kubectl config set-context default \
--cluster=kubernetes \
--user=kube-proxy \
--kubeconfig=kube-proxy.kubeconfig
kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig

拷贝到配置文件指定路径:

cp kube-proxy.kubeconfig /opt/kubernetes/cfg/

4. systemd 管理 kube-proxy

cat > /usr/lib/systemd/system/kube-proxy.service << EOF
[Unit]
Description=Kubernetes Proxy
After=network.target
[Service]
EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf
ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
Restart=on-failure
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF

5. 启动并设置开机启动

systemctl daemon-reload
systemctl start kube-proxy
systemctl enable kube-proxy

7.5 部署 CNI 网络

先准备好 CNI 二进制文件:
下载地址:
https://github.com/containernetworking/plugins/releases/download/v0.8.6/cniplugins-linux-amd64-v0.8.6.tgz
解压二进制包并移动到默认工作目录:

mkdir /opt/cni/bin
tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin

部署 CNI 网络:

wget
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kubeflannel.yml
sed -i -r "s#quay.io/coreos/flannel:.*-amd64#lizhenliang/flannel:v0.12.0-
amd64#g" kube-flannel.yml

默认镜像地址无法访问, 修改为 docker hub 镜像仓库。

kubectl apply -f kube-flannel.yml
kubectl get pods -n kube-system
kubectl get node

部署好网络插件, Node 准备就绪。

7.6 授权 apiserver 访问 kubelet

cat > apiserver-to-kubelet-rbac.yaml<< EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRolemetadata:
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
labels:
kubernetes.io/bootstrapping: rbac-defaults
name: system:kube-apiserver-to-kubelet
rules:
- apiGroups:
- ""
resources:
- nodes/proxy
- nodes/stats
- nodes/log
- nodes/spec
- nodes/metrics
- pods/log
verbs:
- "*"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:kube-apiserver
namespace: ""
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:kube-apiserver-to-kubelet
subjects:- apiGroup: rbac.authorization.k8s.io
kind: User
name: kubernetes
EOF
kubectl apply -f apiserver-to-kubelet-rbac.yaml

7.7 新增加 Worker Node

1. 拷贝已部署好的 Node 相关文件到新节点

在 master 节点将 Worker Node 涉及文件拷贝到新节点 192.168.31.72/73

scp -r /opt/kubernetes root@192.168.31.72:/opt/
scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service
root@192.168.31.72:/usr/lib/systemd/system
scp -r /opt/cni/ root@192.168.31.72:/opt/
scp /opt/kubernetes/ssl/ca.pem root@192.168.31.72:/opt/kubernetes/ssl

2. 删除 kubelet 证书和 kubeconfig 文件

rm /opt/kubernetes/cfg/kubelet.kubeconfig
rm -f /opt/kubernetes/ssl/kubelet*

注: 这几个文件是证书申请审批后自动生成的, 每个 Node 不同, 必须删除重新生成。

3. 修改主机名

vi /opt/kubernetes/cfg/kubelet.conf
--hostname-override=k8s-node1
vi /opt/kubernetes/cfg/kube-proxy-config.yml
hostnameOverride: k8s-node1

4. 启动并设置开机启动

systemctl daemon-reload
systemctl start kubelet
systemctl enable kubelet
systemctl start kube-proxy
systemctl enable kube-proxy

5. 在 Master 上批准新 Node kubelet 证书申请

kubectl get csr
NAME AGE SIGNERNAME
REQUESTOR CONDITION
node-csr-4zTjsaVSrhuyhIGqsefxzVoZDCNKei-aE2jyTP81Uro 89s
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
kubectl certificate approve node-csr-4zTjsaVSrhuyhIGqsefxzVoZDCNKeiaE2jyTP81Uro

6. 查看 Node 状态

Kubectl get node

Node2( 192.168.31.73 ) 节点同上。 记得修改主机名!

kubernetes 高可用集群搭建

1、 概述

Kubernetes 作为容器集群系统, 通过健康检查+重启策略实现了 Pod 故障自我修复能力,
通过调度算法实现将 Pod 分布式部署, 监控其预期副本数, 并根据 Node 失效状态自动在正
常 Node 启动 Pod, 实现了应用层的高可用性。
针对 Kubernetes 集群, 高可用性还应包含以下两个层面的考虑: Etcd 数据库的高可用性
和 Kubernetes Master 组件的高可用性。 而 Etcd 我们已经采用 3 个节点组建集群实现高
可用, 本节将对 Master 节点高可用进行说明和实施。
Master 节点扮演着总控中心的角色, 通过不断与工作节点上的 Kubelet 和 kube-proxy 进
行通信来维护整个集群的健康工作状态。 如果 Master 节点故障, 将无法使用 kubectl 工具
或者 API 任何集群管理。
Master 节点主要有三个服务 kube-apiserver、 kube-controller-mansger 和 kubescheduler, 其中 kube-controller-mansger 和 kube-scheduler 组件自身通过选择机制已
经实现了高可用, 所以 Master 高可用主要针对 kube-apiserver 组件, 而该组件是以 HTTP
API 提供服务, 因此对他高可用与 Web 服务器类似, 增加负载均衡器对其负载均衡即可,
并且可水平扩容。
多 Master 架构图:
在这里插入图片描述

2、 安装 Docker

同单 Master 安装

3、 部署 Master Node

新 Master 内容与已部署的 Master1 节点所有操作一致。 所以我们只需将 Master1 节点所有
K8s 文件拷贝过来, 再修改下服务器 IP 和主机名启动即可。

3.1、 创建 etcd 证书目录

在 Master2( 192.168.31.74) 创建 etcd 证书目录:

mkdir -p /opt/etcd/ssl

3.2、 拷贝文件( Master1 操作)

拷贝 Master1 节点 K8s 所有涉及文件和 etcd 证书:

scp -r /opt/kubernetes root@192.168.31.74:/optscp -r /opt/cni/ root@192.168.31.74:/opt
scp -r /opt/etcd/ssl root@192.168.31.74:/opt/etcd
scp /usr/lib/systemd/system/kube* root@192.168.31.74:/usr/lib/systemd/system
scp /usr/bin/kubectl root@192.168.31.74:/usr/bin

3.3、 删除证书文件

删除 kubelet 证书和 kubeconfig 文件:

rm -f /opt/kubernetes/cfg/kubelet.kubeconfig
rm -f /opt/kubernetes/ssl/kubelet*

3.4、 修改配置文件 IP 和主机名

修改 apiserver、 kubelet 和 kube-proxy 配置文件为本地 IP:

vi /opt/kubernetes/cfg/kube-apiserver.conf
...
--bind-address=192.168.31.74 \
--advertise-address=192.168.31.74 \
...
vi /opt/kubernetes/cfg/kubelet.conf
--hostname-override=k8s-master2
vi /opt/kubernetes/cfg/kube-proxy-config.yml
hostnameOverride: k8s-master2

3.5、 启动设置开机启动

systemctl daemon-reload
systemctl start kube-apiserversystemctl start kube-controller-manager
systemctl start kube-scheduler
systemctl start kubelet
systemctl start kube-proxy
systemctl enable kube-apiserver
systemctl enable kube-controller-manager
systemctl enable kube-scheduler
systemctl enable kubelet
systemctl enable kube-proxy

3.6、 查看集群状态

kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
etcd-1 Healthy {"health":"true"}
etcd-2 Healthy {"health":"true"}
etcd-0 Healthy {"health":"true"}

3.7、 批准 kubelet 证书申请

kubectl get csr
NAME AGE SIGNERNAME
REQUESTOR CONDITION
node-csr-JYNknakEa_YpHz797oKaN-ZTk43nD51Zc9CJkBLcASU 85m
kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending
kubectl certificate approve node-csr-JYNknakEa_YpHz797oKaNZTk43nD51Zc9CJkBLcASU
kubectl get node

4、 部署 Nginx 负载均衡器

( 1) kube-apiserver 高可用架构图:
在这里插入图片描述
( 2) 涉及软件:
Keepalived 是一个主流高可用软件, 基于 VIP 绑定实现服务器双机热备, 在上述拓扑中,
Keepalived 主要根据 Nginx 运行状态判断是否需要故障转移( 偏移 VIP) , 例如当 Nginx
主节点挂掉, VIP 会自动绑定在 Nginx 备节点, 从而保证 VIP 一直可用, 实现 Nginx 高可
用。
Nginx 是一个主流 Web 服务和反向代理服务器, 这里用四层实现对 apiserver 实现负载均
衡。

4.1、 安装软件包( 主/备)

4.2、 Nginx 配置文件( 主/备一样)

4.3、 keepalived 配置文件( Nginx Master)

vrrp_script: 指定检查 nginx 工作状态脚本( 根据 nginx 状态判断是否故障转移)
virtual_ipaddress: 虚拟 IP( VIP)

4.4、 检查 nginx 状态脚本

4.5、 keepalived 配置文件( Nginx Backup)

配置文件中检查 nginx 运行状态脚本。
注: keepalived 根据脚本返回状态码( 0 为工作正常, 非 0 不正常) 判断是否故障转移。

4.6、 启动并设置开机启动

4.7、 查看 keepalived 工作状态

可以看到, 在 ens33 网卡绑定了 192.168.31.88 虚拟 IP, 说明工作正常。

4.8、 Nginx+Keepalived 高可用测试

关闭主节点 Nginx, 测试 VIP 是否漂移到备节点服务器。
在 Nginx Master 执行 pkill nginx在 Nginx Backup, ip addr 命令查看已成功绑定 VIP。

4.9、 访问负载均衡器测试

找 K8s 集群中任意一个节点, 使用 curl 查看 K8s 版本测试, 使用 VIP 访问,如果可以正确获取到 K8s 版本信息, 说明负载均衡器搭建正常。 该请求数据流程: curl ->
vip(nginx) -> apiserver
通过查看 Nginx 日志也可以看到转发 apiserver IP。

4.10、 修改所有 Worker Node 连接 LB VIP

试想下, 虽然我们增加了 Master2 和负载均衡器, 但是我们是从单 Master 架构扩容的, 也
就是说目前所有的 Node 组件连接都还是 Master1, 如果不改为连接 VIP 走负载均衡器, 那
么 Master 还是单点故障。
因此接下来就是要改所有 Node 组件配置文件中的连接 apiserver IP,也就是通过 kubectl get node 命令查看到的节点。
在上述所有 Worker Node 执行:

yum install epel-release -y
yum install nginx keepalived -y
cat > /etc/nginx/nginx.conf << "EOF"
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;include /usr/share/nginx/modules/*.conf;
events {
	worker_connections 1024;
}
#四层负载均衡, 为两台 Master apiserver 组件提供负载均衡
stream {
	log_format main '$remote_addr $upstream_addr - [$time_local] $status
	$upstream_bytes_sent';
	access_log /var/log/nginx/k8s-access.log main;
	upstream k8s-apiserver {
		server 192.168.31.71:6443; # Master1 APISERVER IP:PORT
		server 192.168.31.74:6443; # Master2 APISERVER IP:PORT
	}
	server {
		listen 6443;
		proxy_pass k8s-apiserver;
	}
}
http {
	log_format main '$remote_addr - $remote_user [$time_local] "$request" '
	'$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';
	access_log /var/log/nginx/access.log main;
	sendfile on;
	tcp_nopush on;
	tcp_nodelay on;
	keepalive_timeout 65;
	types_hash_max_size 2048;
	include /etc/nginx/mime.types;
	default_type application/octet-stream;
	server {
		listen 80 default_server;
		server_name _;
		location / {
		}
	}
}
EOF
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
	notification_email {
		acassen@firewall.loc
		failover@firewall.loc
		sysadmin@firewall.loc
	}
	notification_email_from Alexandre.Cassen@firewall.loc
	smtp_server 127.0.0.1
	smtp_connect_timeout 30
	router_id NGINX_MASTER
}
vrrp_script check_nginx {
	script "/etc/keepalived/check_nginx.sh"
}
vrrp_instance VI_1 {
	state MASTER
	interface ens33
	virtual_router_id 51 # VRRP 路由 ID 实例, 每个实例是唯一的
	priority 100 # 优先级, 备服务器设置 90
	advert_int 1 # 指定 VRRP 心跳包通告间隔时间, 默认 1 秒
	authentication {
		auth_type PASS
		auth_pass 1111
	}
	#虚拟 IP
	virtual_ipaddress {
		192.168.31.88/24
	} 
	track_script {
		check_nginx
	}
}
EOF
cat >/etc/keepalived/check_nginx.sh << "EOF"
#!/bin/bash
count=$(ps -ef |grep nginx |egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
exit 1
else
exit 0
fi
EOF
chmod +x /etc/keepalived/check_nginx.sh
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
} n
otification_email_from Alexandre.Cassen@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30
router_id NGINX_BACKUP
} v
rrp_script check_nginx {
script "/etc/keepalived/check_nginx.sh"
} v
rrp_instance VI_1 {state BACKUP
interface ens33
virtual_router_id 51 # VRRP 路由 ID 实例, 每个实例是唯一的
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
} v
irtual_ipaddress {
192.168.31.88/24
} t
rack_script {
check_nginx
}
}
EOF
cat >/etc/keepalived/check_nginx.sh << "EOF"
#!/bin/bash
count=$(ps -ef |grep nginx |egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
exit 1
else
exit 0
fi
EOF
chmod +x /etc/keepalived/check_nginx.sh
systemctl daemon-reloadsystemctl start nginx
systemctl start keepalived
systemctl enable nginx
systemctl enable keepalived
ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group
default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP
group default qlen 1000
link/ether 00:0c:29:04:f7:2c brd ff:ff:ff:ff:ff:ff
inet 192.168.31.80/24 brd 192.168.31.255 scope global noprefixroute ens33
valid_lft forever preferred_lft forever
inet 192.168.31.88/24 scope global secondary ens33
valid_lft forever preferred_lft forever
inet6 fe80::20c:29ff:fe04:f72c/64 scope link
valid_lft forever preferred_lft forever
curl -k https://192.168.31.88:6443/version
{
"major": "1",
"minor": "18",
"gitVersion": "v1.18.3",
"gitCommit": "2e7996e3e2712684bc73f0dec0200d64eec7fe40",
"gitTreeState": "clean",
"buildDate": "2020-05-20T12:43:34Z",
"goVersion": "go1.13.9","compiler": "gc",
"platform": "linux/amd64"
} t
ail /var/log/nginx/k8s-access.log -f
192.168.31.81 192.168.31.71:6443 - [30/May/2020:11:15:10 +0800] 200 422
192.168.31.81 192.168.31.74:6443 - [30/May/2020:11:15:26 +0800] 200 422
角色
IP
k8s-master1
192.168.31.71
k8s-master2
192.168.31.74
k8s-node1
192.168.31.72
k8s-node2
192.168.31.73
sed -i 's#192.168.31.71:6443#192.168.31.88:6443#' /opt/kubernetes/cfg/*
systemctl restart kubelet
systemctl restart kube-proxy
kubectl get node

kubernetes 部署项目

1、 发布 Java 项目
在这里插入图片描述
在这里插入图片描述
(1)制作镜像
(2)控制器管理 Pod
(3)暴露应用

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

kubernetes(k8s)介绍安装和部署实战 的相关文章

  • 从 pod 连接到其他 pod

    基本上 我有一个部署 它创建了 3 个自动扩展的容器 PHP FPM NGINX 和包含应用程序的容器 所有这些都设置了机密 服务和入口 该应用程序还在 PHP FPM 和 NGINX 之间共享项目 因此一切都已设置完毕 由于我想使用 K8
  • Pod 清单写入 Deployment Manifest

    在 Kubernetes 中 将正在运行的 pod 清单转换为具有 x 个副本的部署的简单方法是什么 我尝试获取清单 k get po xyz o yaml gt po1 yaml 然后编辑 yaml 并与部署清单匹配 但这似乎并不容易 我
  • 如何找出 Kubernetes 中可用的端口?

    我想在 kubernetes 集群中的不同端口上运行多个服务 并且想知道如何检查哪些端口可用并且不会与我的服务产生任何冲突 我还想知道每个端口上的服务名称 以便我可以更好地理解我的配置 有类似的问题涉及验证哪个NodePorts已经在使用中
  • Kubernetes 中的暂停镜像有什么用?

    看来在 Windows 上 Kubernetes 启动了一个pause创建的每个 Pod 的图像 这个暂停图像的目的是什么 我在哪里可以找到更多有关它的文档 The pause容器是保存 Pod 网络命名空间的容器 Kubernetes 创
  • Kubernetes ConfigMap 大小限制

    Though resourceQuotas可能会限制命名空间中的配置映射的数量 是否有任何这样的选项来限制单个配置映射的大小 我不喜欢某些用户开始上传大型文本文件作为配置映射 ConfigMap etcd 支持的最大大小是多少 如果 etc
  • 从头开始使用映像部署无法启动

    我正在使用以下内容构建图像Dockerfile FROM golang 1 19 2 bullseye as builder COPY src src WORKDIR src RUN CGO ENABLED 1 go build race
  • 如何在 microk8s 中使用本地 docker 镜像?

    我一直在使用 minikube 在本地测试 Kubernetes 在 minikube 中 我们可以使用本地 docker 镜像eval minikube docker env 命令 我开始探索microk8s 在我运行 Ubuntu 18
  • 使大型静态数据文件可供 kubernetes pod 使用

    我有一些相当大的 UTF 8 数据文件 pod 需要在启动时加载到内存中 从几百 KB 到大约 50 MB 该项目 包括 helm 图表 是开源的 但其中一些文件不是开源的 否则我可能只会将它们包含在图像中 我最初的想法是创建配置映射 但我
  • 从 celery 工作人员到普罗米修斯的自定义指标

    我有一些 celery 工作人员在 kubernetes 下的容器中运行 它们不会由 celery 自动缩放 并且每个都在单个进程中运行 即没有多处理 我想从他们那里获取一堆不同的指标到普罗米修斯中 我研究过 celery promethe
  • kubernetes nginx ingress 无法将 HTTP 重定向到 HTTPS

    我有一个托管在 Google Cloud 平台中的网络应用程序 该应用程序位于负载均衡器后面 而负载均衡器本身位于入口后面 入口设置了 SSL 证书 并按预期接受 HTTPS 连接 但有一个问题 我无法让它将非 HTTPS 连接重定向到 H
  • Kubernetes Pod 中现在几点了?

    假设我有一些 NET Core 代码在 k8s pod 中运行 我要求 DateTime Now 我假设我将从运行 pod 的主机获取日期时间 有没有办法获得在 k8s 集群中一致的日期时间值 容器中的时钟与主机相同 因为它由内核控制 时区
  • 在容器中运行多个相似的进程有意义吗?

    提供有关该问题的背景的简要背景 目前 我和我的团队正在将微服务迁移到 k8s 以减少维护多个部署工具和管道的工作量 我们计划迁移的微服务之一是 ETL Worker 它监听 SQS 上的消息并执行多阶段处理 它是使用 PHP Laravel
  • 如何使用 Prometheus Alert Manager 在 Kubernetes 中触发警报

    我在集群中设置了 kube prometheus https github com coreos prometheus operator tree master contrib kube prometheus https github co
  • kubernetes/openshift 中的请求与限制 cpu

    我在为 Openshift 中的 pod 选择正确的请求和限制设置时遇到一些困境 一些数据 在启动期间 应用程序需要至少 600 毫核才能在 150 秒内完成就绪检查 启动后 200 毫核应该足以让应用程序保持空闲状态 所以我从文档中的理解
  • 允许 Kubernetes 用户列表/获取命名空间

    我有以下用户清单 我希望允许 myapp user 获取集群内所有命名空间的列表 根据我的查找 我应该创建一个 ClusterRole 但我无法真正找到足够的详细信息 是否有所有 apiGroup 以及相应资源和动词的列表 apiVersi
  • 无法使用 minikube 设置 Istio

    我按照 Istio 的官方文档为带有 minikube 的示例 bookinfo 应用程序设置了 Istio 但我得到了无法连接到服务器 net http TLS 握手超时错误 这些是我遵循的步骤 我安装了 kubectl 和 miniku
  • Kubernetes WatchConnectionManager:执行失败:HTTP 403

    我遇到错误Expected HTTP 101 response but was 403 Forbidden 在我使用以下命令设置新的 Kubernetes 集群之后Kubeadm当我提交下面遇到的 pyspark 示例应用程序时 只有一个主
  • Kubernetes 的艰难之路 - 如何设置节点不可调度

    我正在从头开始配置 Kubernetes 集群 原因 它是虚拟机内的本地设置 一切都很好 除了master节点被创建为可调度的 我尝试过分配master通过将所需参数传递给 kubelet 二进制文件来对节点进行标签和适当的污点 不能解决问
  • Google Kubernetes Engine 中的存储 ReadWriteMany

    有没有一种方法能够提供 ReadWriteMany 存储而无需实现存储集群 我能够使用 gcsfuse 提供存储 但速度非常慢 我需要接近 GlusterFS 速度的东西 我目前正在使用 GlusterFS 另一种选择 Google Clo
  • k8s书签解决什么问题?

    我正在尝试做什么 我正在尝试进行部署并监视 k8s 事件 直到部署准备好使用k8s节点API 手表 https github com kubernetes client javascript blob master examples typ

随机推荐

  • 使用putty连接到虚拟机centos被拒绝解决方法

    今天用putty去ssh本地的虚拟机中的centos系统 xff0c 发现连接被拒 xff0c 跳出了这个错误 因为是第一次用putty连接到自己电脑上的虚拟机 xff0c 碰到这个错误 xff0c 我首先想到是不是centos中的防火墙没
  • libvlc 使用mediaplayer 播放rtsp

    环境 ubuntu18 04 vlc3 0 6源码 从 github上下载的vlc 源码 xff0c 默认配置 xff0c 默认编译 xff0c 用命令 vlc rtsp 192 168 43 129 10086 stream 竟然无法播放
  • c语言下,关闭socket的两种方式

    c语言关闭socket的两种方式 一 shutdown include lt sys socket h gt int shutdown int sockfd int how how的方式有三种分别是 SHUT RD xff08 0 xff0
  • 文件系统(七)—图解进程文件操作

    学习文件系统 xff0c 我们的目标是如何实现一个简单的文件系统 xff1f 磁盘上需要什么结构 xff1f 它们需要记录什么 xff1f 如何访问 xff1f 对于这些问题 xff0c 我们就需要理解文件系统的基本工作原理 xff0c 可
  • 解决Docker ADD/COPY 报ADD failed: stat /var/lib/docker/tmp/docker-builder****: no such file or director

    意思就是说 ADD source target 命令找不到source的文件 搜了大致有以下情况 xff1a 没有source文件 xff0c 或者source文件跟Dockerfile不在同一目录 xff0c 或者命令docker bui
  • Qt各个版本和插件的下载方法

    Qt及其插件的下载 网址 xff1a http master qt io 1 输入网址 后 2 点开archive后 3 打开qt后 xff0c 出来的是qt的版本 4 下载5 2版本为例 xff0c 打开5 2 后 5 里面有两个版本5
  • Centos7 安装Docker以及图形管理界面

    Docker的安装 1 确保系统中没有旧版本 如果安装过的话 xff0c 没有安装则忽略此步 yum span class token operator span y remove docker docker common docker s
  • Android汽车服务篇(三) CarPropertyService下篇

    一 简介 上篇文章介绍了Android汽车服务篇 二 CarPropertyService上篇 我们继续看一看看CarPropertyService 这个服务也是很重要的 绝大部分与车辆硬件功能相关联的属性 如空调 车舱功能 车辆传感器等都
  • PPTV面试算法思考-最长对称子字符串

    题目 最近在微信公众号里看看到了一个PPTV的面试算法题 xff0c 感觉难度适中 xff0c 想试下 题目的内容为求一个字符串的最长对称子字符串 如 xff1a 输入 输出 abba 4 abad 3 acccbaa 3 我的算法1 自己
  • mardown语法详解

    这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题 xff0c 有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中 居左 居右SmartyP
  • C++

    由于见到论坛上不少找书的 xff0c 于是就稍稍汇总总结了一下 xff0c 作为本人即将推出的 C 43 43 资源大汇 系列文章的引子 本文只是初稿 xff0c 其中有不少的纰漏 笔误 打误 xff08 打字错误 xff09 希望各位纠正
  • Tx2 设置静态IP的两种方法

    Tx2设置静态ip的两种方法 Tx2静态ip设置可通过桌面右上角的有线连接配置中的ipv4的配置来设置 xff1b Tx2静态ip设置的第二种方法是通过间接修改ipv4的配置来设置 xff1b 用ifconfig来查看你使用的是哪个网络设备
  • 七 Gazebo学习总结之传感器的添加

    本文展示的是使用者怎么直接通过Gazebo其他模型来创建复杂的模型 xff0c 以及使用 lt include gt 和 lt joint gt 标签来连接一个复杂模型的不同部分 1 增加一个激光器 a 进入先前教程的模型目录中 cd ga
  • STM32、FreeRTOS—— SVC 和 PendSV

    问 I went through the xTaskStartSechudler function which ends up triggering the SVC instruction and i came to know that i
  • MYNTEYE-SDK-ROS-Kinetic-VINS-Mono环境搭建到运行(Ubuntu 16.04)非常详细

    一 首先安装ROS环境 1 确保系统软件处于最新版 xff1a sudo apt get update 2 打开终端 xff0c 输入命令 wget https raw githubusercontent com oroca oroca r
  • win7关机一直卡在正在关机

    win7关机一直卡在正在关机 尝试用win7系统准备工具 xff08 sysprep xff09 来恢复到系统的初始状态 步骤 xff1a 1 win 43 R打开运行窗口 xff1b 2 在窗口中输入 xff1a sysprep xff0
  • Jetson TX2学习笔记(一):软硬件基础环境配置

    拿到了Jetson TX2套件 xff0c 在给套件安装开发环境时踩了很多坑 上网查阅的资料也都没能解决问题 xff0c 这里把成功安装步骤一一记录下来 xff0c 同时将所遇到且网上未提及的问题也进行一下分析 先说一下 xff0c Jet
  • 启动Docker,出现“Got permission denied while trying to connect to the Docker daemon socket“的情况

    启动docker时 xff0c 出现 Got permission denied while trying to connect to the Docker daemon socket 的情况 解决方法 xff1a docker守护进程启动
  • 【matlab调用m文件方法】

    matlab如何调用m文件 matlab调用m文件方法
  • kubernetes(k8s)介绍安装和部署实战

    kubernetes 基本介绍 kubernetes xff0c 简称 K8s xff0c 是用 8 代替 8 个字符 ubernete 而成的缩写 是一个开源 的 xff0c 用于管理云平台中多个主机上的容器化的应用 xff0c Kube