Flink on k8s 环境搭建(一)
Flink on Yarn的环境搭建过程中,需要进行配置较多,且需要搭建zookeeper Hadoop Yarn 等相关组件,安装流程比较复杂,集群出现问题重新安装的流程也比较复杂,且Yarn的3个节点中 只能起了 3个resourceManager和1个NodeManager,Flink 作业申请资源时只能 向NodeManager的节点申请资源,整体有资源瓶颈的隐患(后继flink作业会越来
Flink on k8s 环境搭建(二)_wangqiaowq的博客-CSDN博客
Flink on Yarn的环境搭建过程中,需要进行配置较多,且需要搭建zookeeper Hadoop Yarn 等相关组件,安装流程比较复杂,集群出现问题重新安装的流程也比较复杂,且Yarn的3个节点中 只能起了 3个resourceManager和1个NodeManager,Flink 作业申请资源时只能 向NodeManager的节点申请资源,整体有资源瓶颈的隐患(后继flink作业会越来越多),现在尝试进行Flink on k8s 的环境搭建。
Flink on Kubernetes(也称为Flink on K8s)是指在Kubernetes集群上运行Apache Flink分布式流处理框架。
Kubernetes是一个开源的容器编排平台,可以帮助管理容器化的应用程序,并提供弹性、可伸缩和可靠的部署环境。结合Flink和Kubernetes,可以实现高效的大规模数据流处理。
Flink on K8s 提供了以下优势:
1. 弹性伸缩:Kubernetes可以根据负载自动扩展和收缩Flink作业所需的任务资源。
2. 容器化管理:Flink作业可以作为容器运行,并且可以受益于Kubernetes的容器化管理功能,例如版本管理、生命周期管理和监控等。
3. 故障恢复:Kubernetes可以自动检测和替代故障节点,提供高可用性和容错性,确保作业持续运行。
要在Kubernetes上运行Flink,您可以使用Apache Flink官方提供的Kubernetes部署工具或其他第三方工具,如Helm Chart。
通过Kubernetes部署Flink,您可以使用Kubernetes的API和资源管理功能,有效地管理和部署您的Flink作业。这样,您可以轻松地扩展Flink集群的规模,实现动态自动化的资源分配和作业调度。
K8s 环境搭建
先部署 1master 和 2node 节点,后面再加一个 master 节点
一、前期工作(所有节点)
1、修改主机名
2、配置 ssh 互信
# 直接一直回车就行
ssh-keygen
ssh-copy-id -i ~/.ssh/id_rsa.pub root@bigData05
ssh-copy-id -i ~/.ssh/id_rsa.pub root@bigData06
ssh-copy-id -i ~/.ssh/id_rsa.pub root@bigData08
3、时间同步
yum install chrony -y
systemctl start chronyd
systemctl enable chronyd
chronyc sources
3)确保每个节点上 MAC 地址和 product_uuid 的唯一性
- 你可以使用命令 ip link来获取网络接口的 MAC 地址
- 可以使用 sudo cat /sys/class/dmi/id/product_uuid 命令对 product_uuid 校验
一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 Kubernetes 使用这些值来唯一确定集群中的节点。 如果这些值在每个节点上不唯一,可能会导致安装 失败。
4、关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
5、关闭 swap
# 临时关闭;关闭swap主要是为了性能考虑
swapoff -a
# 可以通过这个命令查看swap是否关闭了
free
# 永久关闭
sed -ri 's/.*swap.*/#&/' /etc/fstab
6、禁用 SELinux
# 临时关闭
setenforce 0
# 永久禁用
sed -i 's/^SELINUX=enforcing$/SELINUX=disabled/' /etc/selinux/config
7、允许 iptables 检查桥接流量(可选)
- 确保 br_netfilter 模块被加载。这一操作可以通过运行 lsmod | grep br_netfilter 来完成。若要显式加载该模块,可执行 sudo modprobe br_netfilter。
- 为了让你的 Linux 节点上的 iptables 能够正确地查看桥接流量,你需要确保在你的 sysctl 配置中将 net.bridge.bridge-nf-call-iptables 设置为 1。所有节点都执行以下命令:
cat /etc/modules-load.d/k8s.conf
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat /etc/sysctl.d/k8s.conf
# 设置所需的 sysctl 参数,参数在重新启动后保持不变
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
# 应用 sysctl 参数而不重新启动
sudo sysctl --system
查看:
cat /etc/sysctl.d/k8s.conf
在其他3个节点上重复以上操作
5)检查所需端口
netstat -tuln | grep 10250
=》master节点
协议 | 方向 | 端口范围 | 作用 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 6443 | Kubernetes API 服务器 | 所有组件 |
TCP | 入站 | 2379-2380 | etcd | 服务器客户端 API |
TCP | 入站 | 10250 | Kubelet API | kubelet 自身、控制平面组件 |
TCP | 入站 | 10251 | kube-scheduler | kube-scheduler 自身 |
TCP | 入站 | 10252 | kube-controller-manager | kube-controller-manager 自身 |
=》node(work)节点
协议 | 方向 | 端口范围 | 作用 | 使用者 |
---|---|---|---|---|
TCP | 入站 | 10250 | Kubelet API | kubelet 自身、控制平面组件 |
TCP | 入站 | 30000-32767 | NodePort 服务 | 所有组件 |
2)安装容器 docker(所有节点)
# 配置yum源
cd /etc/yum.repos.d ; mkdir bak; mv CentOS-*.repo bak/
# centos7 (本次使用centos7)
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
# centos8 (如果使用centos8 可下载这个)
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-8.repo
# 安装yum-config-manager配置工具
yum -y install yum-utils
# 设置yum源
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装docker-ce版本
yum install -y docker-ce
这个是由于系统已经有安装过docker了,可能是之前敲过了yum -y install docker或者其他方式安装过了导致与冲突,可以使用yum list installed | grep docker快速查看是否有其他已安装的docker程序,有的话全部卸载后再安装就行了
yum list installed | grep docker
yum -y remove docker-client
通过yum安装docker-ce报错,是因为本机安装过多次造成的,如下所示,需要解决掉冲突依赖,从新安装
rpm -e docker-common.x86_64 或 yum -y remove docker-common
重新安装
yum install -y docker-ce
yum list installed | grep docker
# 启动
systemctl start docker
# 开机自启
systemctl enable docker
# 查看版本号
docker --version
# 查看版本具体信息
docker version
# Docker镜像源设置
# 修改文件 /etc/docker/daemon.json,没有这个文件就创建
# 添加以下内容后,重启docker服务:
cat >/etc/docker/daemon.json<<EOF
{
"registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF
# 加载
systemctl reload docker
# 查看
systemctl status docker containerd
【温馨提示】dockerd 实际真实调用的还是 containerd 的 api 接口,containerd 是 dockerd 和 runC 之间的一个中间交流组件。所以启动 docker 服务的时候,也会启动 containerd 服务的。
3)配置 k8s yum 源(所有节点)
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[k8s]
name=k8s
enabled=1
gpgcheck=0
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
EOF
4)将 sandbox_image 镜像源设置为阿里云 google_containers 镜像源(所有节点)
# 导出默认配置,config.toml这个文件默认是不存在的
containerd config default > /etc/containerd/config.toml
grep sandbox_image /etc/containerd/config.toml
sed -i "s#registry.k8s.io/pause#registry.aliyuncs.com/google_containers/pause#g" /etc/containerd/config.toml
grep sandbox_image /etc/containerd/config.toml
5)配置 containerd cgroup 驱动程序 systemd(所有节点)
kubernets 自v 1.24.0 后,就不再使用 docker.shim,替换采用 containerd 作为容器运行时端点。因此需要安装 containerd(在 docker 的基础下安装),上面安装 docker 的时候就自动安装了 containerd 了。这里的 docker 只是作为客户端而已。容器引擎还是 containerd。
如果你使用Docker作为K8S容器运行时的话,kubelet需要先要通过 dockershim 去调用Docker,再通过Docker去调用containerd。
如果你使用containerd作为K8S容器运行时的话,由于containerd内置了 CRI (Container Runtime Interface:容器运行时接口)插件,kubelet可以直接调用containerd。
grep SystemdCgroup /etc/containerd/config.toml
sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' /etc/containerd/config.toml
# 应用所有更改后,重新启动containerd
systemctl restart containerd
6)开始安装 kubeadm,kubelet 和 kubectl(master 节点)
-
kubeadm:用来初始化集群的指令。
-
kubelet:在集群中的每个节点上用来启动 Pod 和容器等。
-
kubectl:用来与集群通信的命令行工具。
# 不指定版本就是最新版本,当前最新版就是1.24.1
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
或指定版本
yum install -y kubelet-1.24.1 kubeadm-1.24.1 kubectl-1.24.1 --disableexcludes=kubernetes
# disableexcludes=kubernetes:禁掉除了这个kubernetes之外的别的仓库
安装 yum install -y kubernetes-cni
重启containerd后生效 systemctl restart containerd.service
# 设置为开机自启并现在立刻启动服务 --now:立刻启动服务
systemctl start kubelet
systemctl enable --now kubelet
# 查看状态,这里需要等待一段时间再查看服务状态,启动会有点慢
systemctl status kubelet -l
常见问题如下:
1、发现无法启动,更换了k8s yum源
2 这些错误可能是由于已经存在相同名称的Pod而导致创建失败
-
删除已存在的 Pod:如果
pods "already exists"
错误是指的同名的 Pod 已经在集群中存在,你可以尝试删除这个重复的 Pod,然后再次创建你想要的镜像 Pod。-
使用
kubectl delete pod <pod名称>
命令删除已存在的 Pod。例如,kubectl delete pod my-pod
将删除名称为 “my-pod” 的 Pod。 -
请注意,删除 Pod 可能会导致一段时间内的服务中断或应用程序停止。请根据你的具体情况选择合适的时间来执行删除操作
-
kubectl delete pod kube-apiserver-bigdata07 -n kube-system --grace-period=0 --force
kubectl delete pod kube-scheduler-bigdata07
-n kube-system --grace-period=0 --force
kubectl delete pod etcd-bigdata07 -n kube-system --grace-period=0 --force
kubectl get pods -o wide -n kube-system
3、服务器尚未初始化
这个错误消息 “GenericPLEG: Unable to retrieve pods” 是 Kubernetes Pod Lifecycle Event Generator(PLEG)遇到的问题。错误消息中的 “rpc error: code = Unknown desc = server is not initialized yet” 表示服务器尚未初始化。
出现这个错误的原因可能是 Kubernetes 控制平面组件(如 kube-apiserver、kube-scheduler 或 kube-controller-manager)尚未完全启动或处于不可用状态。
kubectl get pod -n kube-system
查看版本
kubectl version
yum info kubeadm
7)使用 kubeadm 初始化集群(master 节点)
最好提前把镜像下载好,这样安装快
docker pull registry.aliyuncs.com/google_containers/kube-apiserver:v1.24.1
docker pull registry.aliyuncs.com/google_containers/kube-controller-manager:v1.24.1
docker pull registry.aliyuncs.com/google_containers/kube-scheduler:v1.24.1
docker pull registry.aliyuncs.com/google_containers/kube-proxy:v1.24.1
docker pull registry.aliyuncs.com/google_containers/pause:3.7
docker pull registry.aliyuncs.com/google_containers/etcd:3.5.3-0
docker pull registry.aliyuncs.com/google_containers/coredns:v1.8.6
集群初始化
kubeadm reset
rm -rf /etc/cni/net.d
rm -rf $HOME/.kube/config
kubeadm init \
--apiserver-advertise-address=192.168.1.247 \
--image-repository registry.aliyuncs.com/google_containers \
--kubernetes-version v1.27.3 \
--service-cidr=10.96.0.0/12 \
--pod-network-cidr=10.100.0.0/16\
--ignore-preflight-errors=all
或
kubeadm init --apiserver-advertise-address=192.168.1.244 --image-repository registry.aliyuncs.com/google_containers --kubernetes-version v1.27.4 --service-cidr=10.1.0.0/16 --pod-network-cidr=10.244.0.0/16
#--service-cidr=10.96.0.0/12
表示Kubernetes服务将使用范围为10.96.0.0到10.111.255.255的IP地址,共有4096个子网可用。服务CIDR通常用于给Kubernetes集群中各类内部服务分配IP地址。
# –image-repository string: 这个用于指定从什么位置来拉取镜像(1.13版本才有的),默认值是k8s.gcr.io,我们将其指定为国内镜像地址:registry.aliyuncs.com/google_containers
# –kubernetes-version string: 指定kubenets版本号,默认值是stable-1,会导致从https://dl.k8s.io/release/stable-1.txt下载最新的版本号,我们可以将其指定为固定版本(v1.22.1)来跳过网络请求。
# –apiserver-advertise-address 指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。这里的ip为master节点ip,记得更换。
# –pod-network-cidr 指定 Pod 网络的范围。Kubernetes 支持多种网络方案,而且不同网络方案对 –pod-network-cidr有自己的要求,这里设置为10.244.0.0/16 是因为我们将使用 flannel 网络方案,必须设置成这个 CIDR。--pod-network-cidr=10.100.0.0/16
指定了 Pod 网络的 CIDR 范围为 10.100.0.0 到 10.100.255.255。这个范围内有 65536 个 IP 地址。可以选择的 VIP 地址范围是 10.100.0.1 到 10.111.255.254。
例如采用如下VIP
- IP 地址:10.96.0.12
- 子网掩码:/24 (或称为 255.255.255.0)
- 这意味着该虚拟 IP 地址属于 10.96.0.0 网络中的一个主机,在该网络中可用的 IP 地址范围是 10.96.0.1 到 10.96.0.254,子网掩码为 255.255.255.0。
# --control-plane-endpoint cluster-endpoint 是映射到该 IP 的自定义 DNS 名称,这里配置hosts映射:192.168.0.113 cluster-endpoint。 这将允许你将 --control-plane-endpoint=cluster-endpoint 传递给 kubeadm init,并将相同的 DNS 名称传递给 kubeadm join。 稍后你可以修改 cluster-endpoint 以指向高可用性方案中的负载均衡器的地址。
配置环境变量
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
vim /etc/profile
export KUBECONFIG=/etc/kubernetes/admin.conf
source /etc/profile
8)安装 Pod 网络插件(CNI:Container Network Interface)(master)
你必须部署一个基于 Pod 网络插件的 容器网络接口 (CNI),以便你的 Pod 可以相互通信。
flannel 没安装成功 改为 安装 calico
# 最好提前下载镜像(所有节点)
docker pull quay.io/coreos/flannel:v0.14.0
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kubectl get pods -A
kubectl get nodes
修改为10.100.0.0/16
kubectl apply -f kube-flannel.yml
kubectl get pods -A
kubectl get nodes
kubectl describe pods -n kube-system coredns-7bdc4cb885-b75bp
删除污点
由于是单节点,master默认不接受任务调度,需要删除污点。
kubectl describe node bigdata08 |grep Taints
发现master节点有污点(即NoSchedule字样),删除污点
kubectl taint node bigdata08 node-role.kubernetes.io/master-
kubectl taint node bigdata08 node-role.kubernetes.io/control-plane-
改装calico
下载calico wget https://docs.projectcalico.org/manifests/calico.yaml
关闭IPIP模式
calico网络,默认是ipip模式。会在每台node主机创建一个tunl0网口,这个隧道链接所有的node容器网络,官网推荐不同的ip网段适合。
我们这里关闭IPIP模式。
在DaemonSet部分 calico-node的pod的变量中,修改CALICO_IPV4POOL_IPIP值为off
- name: CALICO_IPV4POOL_IPIP
#value: "Always"
value: "off"
修改pod的网段
修改CALICO_IPV4POOL_CIDR为k8s集群的pod网段
同样也在DaemonSet 中, calico-node的pod的变量里,修改如下:
- name: CALICO_IPV4POOL_CIDR
value: "10.244.0.0/16"
kubectl apply -f calico.yam
kubectl get pods -A
9)node 节点加入 k8s 集群
在work节点先安装 kubelet
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
安装 yum install -y kubernetes-cni
重启containerd后生效 systemctl restart containerd.service
# 设置为开机自启并现在立刻启动服务 --now:立刻启动服务
systemctl start kubelet
systemctl enable --now kubelet
systemctl status kubelet
在master节点上
kubeadm token create --print-join-command
可以生成:
kubeadm join 192.168.1.244:6443 --token kc0md9.e6s96yyukvuquque --discovery-token-ca-cert-hash sha256:6246e998f96106f9aea4509c1b162d7ffa578838e086c8bc6941390448191597
添加worker节点(worker)
在其他节点上执行以下 命令 加入 k8s集群:
#在所有worker节点运行此命令,即可将节点加入集群(如安装过可以先kubeadm reset)
kubeadm reset
rm -rf /etc/cni/net.d
rm -rf $HOME/.kube/config
kubeadm join 192.168.1.244:6443 --token kc0md9.e6s96yyukvuquque --discovery-token-ca-cert-hash sha256:6246e998f96106f9aea4509c1b162d7ffa578838e086c8bc6941390448191597
kubectl get nodes
#worker节点是无法运行kubectl命令的,因为worker节点没有admin.conf文件
#若需在worker节点使用kubectl命令,需要将admin.conf配置文件拷贝到worker节点,再执行以下命令:
scp root@master:/etc/kubernetes/admin.conf /etc/kubernetes/
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> /etc/profile
source /etc/profile
这里需要等待一段时间,再查看节点节点状态,因为需要安装 kube-proxy 和 flannel。
在其他节点上
kubeadm reset
kubeadm join 192.168.1.247:6443 --token no32d3.k1zmaqlnjoswitvz --discovery-token-ca-cert-hash sha256:6246e998f96106f9aea4509c1b162d7ffa578838e086c8bc6941390448191597
kubectl get nodes
scp /etc/kubernetes/admin.conf root@bigData08:/etc/kubernetes/
scp /etc/kubernetes/admin.conf root@bigData06:/etc/kubernetes/
scp /etc/kubernetes/admin.conf root@bigData05:/etc/kubernetes/
10)配置 IPVS
【问题】集群内无法 ping 通 ClusterIP(或 ServiceName)
1、加载 ip_vs 相关内核模块
modprobe -- ip_vs
modprobe -- ip_vs_sh
modprobe -- ip_vs_rr
modprobe -- ip_vs_wrr
所有节点验证开启了 ipvs:
lsmod |grep ip_vs
3、编辑 kube-proxy 配置文件,mode 修改成 ipvs
kubectl edit configmap -n kube-system kube-proxy
4、重启 kube-proxy
# 先查看
kubectl get pod -n kube-system | grep kube-proxy
# 再delete让它自拉起
kubectl get pod -n kube-system | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'
# 再查看
kubectl get pod -n kube-system | grep kube-proxy
5、查看 ipvs 转发规则
ipvsadm -Ln
再次查看 kubectl get nodes
11)集群高可用配置 (非高可用可以忽略)
配置高可用(HA)Kubernetes 集群实现的两种方案:
- 使用堆叠(stacked)控制平面节点,其中 etcd 节点与控制平面节点共存(本章使用),架构图如下:
这里新增一台机器作为另外一个 master 节点:192.168.0.116 配置跟上面 master 节点一样。只是不需要最后一步初始化了。
1、修改主机名和配置 hosts 所有节点都统一如下配置:
2、配置 ssh 互信
3、时间同步
7、关闭防火墙
4、关闭 swap
5、禁用 SELinux
6、允许 iptables 检查桥接流量(可选,所有节点)
7、安装容器 docker(所有节点)
8、配置 k8s yum 源(所有节点)
9、将 sandbox_image 镜像源设置为阿里云 google_containers 镜像源(所有节点)
10、配置 containerd cgroup 驱动程序
以上操作同上一个master节点,应都已经配置了
12、加入 k8s 集群
k8s-新增master节点
在当前唯一的master节点上运行如下命令
第一步:
kubeadm init phase upload-certs --upload-certs
7d1d592d13c91fb41be143558bd2ce7e0bf33a80e0233c8ca2582139762a8782
第二步:
kubeadm token create --print-join-command
kubeadm join 192.168.1.247:6443 --token keyixf.jr0ovq2zqz09tvur --discovery-token-ca-cert-hash sha256:6246e998f96106f9aea4509c1b162d7ffa578838e086c8bc6941390448191597
第三步:
在当前master节点:
查看kubeadm-config.yaml
kubectl -n kube-system get cm kubeadm-config -oyaml
发现没有controlPlaneEndpoint
添加controlPlaneEndpoint
kubectl -n kube-system edit cm kubeadm-config
大概在这么个位置:
kind: ClusterConfiguration
kubernetesVersion: v1.18.0
controlPlaneEndpoint: 172.16.0.56:6443
然后再在准备添加为master的节点上执行kubeadm join的命令
step 2
从master1 拷贝证书到master2
scp /etc/kubernetes/pki/ca. root@192.168.1.248:/etc/kubernetes/
scp /etc/kubernetes/pki/ca.* root@192.168.1.248:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/sa.* root@192.168.1.248:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/front-proxy-ca.* root@192.168.1.248:/etc/kubernetes/pki/
在master2上 mkdir -p /etc/kubernetes/pki/etcd
scp /etc/kubernetes/pki/etcd/ca.* root@192.168.1.248:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/pki/etcd/ca.* root@192.168.1.248:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/admin.conf root@192.168.1.248:/etc/kubernetes/
第四步:
将得到的token和key进行拼接,得到如下命令:
kubeadm join 192.168.1.247:6443 --token keyixf.jr0ovq2zqz09tvur --discovery-token-ca-cert-hash sha256:6246e998f96106f9aea4509c1b162d7ffa578838e086c8bc6941390448191597 --control-plane --certificate-key 7d1d592d13c91fb41be143558bd2ce7e0bf33a80e0233c8ca2582139762a8782
在需要加入的新master节点上 执行拼接后的命令
kubeadm join 192.168.1.247:6443 --token keyixf.jr0ovq2zqz09tvur --discovery-token-ca-cert-hash sha256:6246e998f96106f9aea4509c1b162d7ffa578838e086c8bc6941390448191597 --control-plane --certificate-key 7d1d592d13c91fb41be143558bd2ce7e0bf33a80e0233c8ca2582139762a8782
注意:
1、要加上--control-plane --certificate-key ,不然就会添加为node节点而不是master
2、join的时候节点上不要部署,如果部署了kubeadm reset后再join
kubeadm reset
# --control-plane 标志通知 kubeadm join 创建一个新的控制平面。加入master必须加这个标记
# --certificate-key ... 将导致从集群中的 kubeadm-certs Secret 下载控制平面证书并使用给定的密钥进行解密。这里的值就是上面这个命令(kubeadm init phase upload-certs --upload-certs)打印出的key。
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
kubectl get pods -A -owide
虽然现在已经有两个 master 了,但是对外还是只能有一个入口的,所以还得要一个负载均衡器,如果一个 master 挂了,会自动切到另外一个 master 节点。
12)部署 Nginx+Keepalived 高可用负载均衡器
参考:
1、安装 Nginx 和 Keepalived
# 在两个master节点上执行
yum install nginx keepalived -y
yum -y install epel-release
yum install nginx -y
2、Nginx 配置 在两个 master 节点配置
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 {
# Master APISERVER IP:PORT
server 192.168.1.247:6443;
# Master2 APISERVER IP:PORT
server 192.168.1.248:6443;
}
server {
listen 16443;
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
3、Keepalived 配置(master)
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from wangqiaowqo_07@qq.com
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 {
10.96.0.12/24
}
track_script {
check_nginx
}
}
EOF
- vrrp_script:指定检查 nginx 工作状态脚本(根据 nginx 状态判断是否故障转移)
- virtual_ipaddress:虚拟 IP(VIP) 检查 nginx 状态脚本:
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
4、Keepalived 配置(backup)
cat > /etc/keepalived/keepalived.conf << EOF
global_defs {
notification_email {
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_from wangqiaowqo_07@qq.com
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 ens192 # 改为自己机器的网卡
virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的
priority 100 # 优先级,备服务器设置 90
advert_int 1 # 指定VRRP 心跳包通告间隔时间,默认1秒
authentication {
auth_type PASS
auth_pass 1111
}
# 虚拟IP
virtual_ipaddress {
10.96.0.12/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
5、启动并设置开机启动
systemctl daemon-reload
systemctl restart nginx && systemctl enable nginx && systemctl status nginx
1.nginx -V 确保nginx 安装了 –with -stream;如果没有,重新用yum install nginx -y安装
2. 安装 yum -y install epel-release
3. yum -y install nginx-all-modules.noarch
4、nginx -t -c /etc/nginx/nginx.conf
systemctl restart nginx && systemctl enable nginx && systemctl status nginx
systemctl restart keepalived && systemctl enable keepalived && systemctl status keepalived
ip a 查看 暂时VIP没有配置成功,后继持续关注。
curl -k https://cluster-endpoint:16443/version
二、k8s 管理平台 dashboard 环境部署
但是这个只能内部访问,所以要外部访问,要么部署 ingress,要么就是设置 service NodePort 类型。这里选择 service 暴露端口。
recommended.yaml 如下:
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: v1
kind: Namespace
metadata:
name: kubernetes-dashboard
---
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
ports:
- port: 443
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kubernetes-dashboard
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-csrf
namespace: kubernetes-dashboard
type: Opaque
data:
csrf: ""
---
apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-key-holder
namespace: kubernetes-dashboard
type: Opaque
---
kind: ConfigMap
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-settings
namespace: kubernetes-dashboard
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
rules:
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster", "dashboard-metrics-scraper"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
verbs: ["get"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
rules:
# Allow Metrics Scraper to get metrics from the Metrics server
- apiGroups: ["metrics.k8s.io"]
resources: ["pods", "nodes"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: kubernetes-dashboard
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kubernetes-dashboard
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: kubernetes-dashboard
image: kubernetesui/dashboard:v2.6.0
imagePullPolicy: Always
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
- --namespace=kubernetes-dashboard
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
---
kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
ports:
- port: 8000
targetPort: 8000
selector:
k8s-app: dashboard-metrics-scraper
---
kind: Deployment
apiVersion: apps/v1
metadata:
labels:
k8s-app: dashboard-metrics-scraper
name: dashboard-metrics-scraper
namespace: kubernetes-dashboard
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: dashboard-metrics-scraper
template:
metadata:
labels:
k8s-app: dashboard-metrics-scraper
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: dashboard-metrics-scraper
image: kubernetesui/metrics-scraper:v1.0.8
ports:
- containerPort: 8000
protocol: TCP
livenessProbe:
httpGet:
scheme: HTTP
path: /
port: 8000
initialDelaySeconds: 30
timeoutSeconds: 30
volumeMounts:
- mountPath: /tmp
name: tmp-volume
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsUser: 1001
runAsGroup: 2001
serviceAccountName: kubernetes-dashboard
nodeSelector:
"kubernetes.io/os": linux
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule
volumes:
- name: tmp-volume
emptyDir: {}
重新部署
kubectl delete -f recommended.yaml
kubectl apply -f recommended.yaml
kubectl get svc,pods -n kubernetes-dashboard -o wide
创建登录用户
cat >ServiceAccount.yaml<<EOF
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
EOF
kubectl apply -f ServiceAccount.yaml
创建并获取登录 token
kubectl -n kubernetes-dashboard create token admin-user
eyJhbGciOiJSUzI1NiIsImtpZCI6InhyNnZ4UmEwcG9uZFFidVFWR3VQWHRFSmxzUjNGTVppUS1mZ3F1NmtsdUkifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjkwMjU2MTMzLCJpYXQiOjE2OTAyNTI1MzMsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJhZG1pbi11c2VyIiwidWlkIjoiYTkxMGMyMGItNjZkYS00MmYzLWI5NTQtZTRhOGVmZmRhNTNiIn19LCJuYmYiOjE2OTAyNTI1MzMsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlcm5ldGVzLWRhc2hib2FyZDphZG1pbi11c2VyIn0.vxsBgAdHTHkDbONYtop09bJGt2FQ2EOAjMEGj4U7VD6IkVjioh2xBdfQfglVD1q-r4qSdfB_d7URIOzkW1vqcckOPayfaDm0VNY2p3LmoklK0X1QtxQfiVr5zG_AfPfbv-D4r0zusMFOOjnicUThGIAIhGBS5GWWFjG3Dmz9tPtpekrqIFFbpk9JG8YvOecs7t-lb1iOidcU5PcpIl6wkgX0ERZ5Ye5B8CQvI7LIYXyXU9-EKTH6ZWrwWAGC5B4ZNYVb_m1IKx3X-k63rvRB4hgU39h11X5aZPi8tNCKiOPjeT49BWpmvFM_5q8A7yV-WGo2_ojG9UUS5il76Kc2qA
在页面空白处点击一下,然后输入thisisunsafe后,页面会要求输入上面的token
----------------------------------------------------------------------------------------------------------
更多推荐
所有评论(0)