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、修改主机名

     

docker部署flink没有kafka插件 docker搭建flink集群_ci

     

docker部署flink没有kafka插件 docker搭建flink集群_flink_02

 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

docker部署flink没有kafka插件 docker搭建flink集群_Pod_03

3)确保每个节点上 MAC 地址和 product_uuid 的唯一性

  • 你可以使用命令 ip link来获取网络接口的 MAC 地址
  • 可以使用 sudo cat /sys/class/dmi/id/product_uuid 命令对 product_uuid 校验

一般来讲,硬件设备会拥有唯一的地址,但是有些虚拟机的地址可能会重复。 Kubernetes 使用这些值来唯一确定集群中的节点。 如果这些值在每个节点上不唯一,可能会导致安装 失败。

docker部署flink没有kafka插件 docker搭建flink集群_docker_04

 

docker部署flink没有kafka插件 docker搭建flink集群_Pod_05

 4、关闭防火墙

systemctl stop firewalld
systemctl disable firewalld

5、关闭 swap

# 临时关闭;关闭swap主要是为了性能考虑
swapoff -a
# 可以通过这个命令查看swap是否关闭了
free

docker部署flink没有kafka插件 docker搭建flink集群_Pod_06


# 永久关闭

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。

docker部署flink没有kafka插件 docker搭建flink集群_flink_07

  • 为了让你的 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

docker部署flink没有kafka插件 docker搭建flink集群_docker_08

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

docker部署flink没有kafka插件 docker搭建flink集群_docker_09

# 应用 sysctl 参数而不重新启动
sudo sysctl --system

docker部署flink没有kafka插件 docker搭建flink集群_ci_10

查看: 

cat /etc/sysctl.d/k8s.conf

docker部署flink没有kafka插件 docker搭建flink集群_Pod_11

在其他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/

docker部署flink没有kafka插件 docker搭建flink集群_docker_12


# 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部署flink没有kafka插件 docker搭建flink集群_flink_13


# 安装docker-ce版本

yum install -y docker-ce

docker部署flink没有kafka插件 docker搭建flink集群_docker_14

这个是由于系统已经有安装过docker了,可能是之前敲过了yum -y install docker或者其他方式安装过了导致与冲突,可以使用yum list installed | grep docker快速查看是否有其他已安装的docker程序,有的话全部卸载后再安装就行了 

yum list installed | grep docker

docker部署flink没有kafka插件 docker搭建flink集群_docker_15

yum -y remove docker-client

docker部署flink没有kafka插件 docker搭建flink集群_大数据_16

 通过yum安装docker-ce报错,是因为本机安装过多次造成的,如下所示,需要解决掉冲突依赖,从新安装

docker部署flink没有kafka插件 docker搭建flink集群_docker_17

rpm -e docker-common.x86_64  或 yum -y remove docker-common

重新安装

yum install -y docker-ce

docker部署flink没有kafka插件 docker搭建flink集群_docker_18

docker部署flink没有kafka插件 docker搭建flink集群_flink_19

  yum list installed | grep docker

docker部署flink没有kafka插件 docker搭建flink集群_flink_20

 # 启动
systemctl start docker
# 开机自启
systemctl enable docker
# 查看版本号
docker --version
# 查看版本具体信息
docker version

docker部署flink没有kafka插件 docker搭建flink集群_flink_21

 # Docker镜像源设置
# 修改文件 /etc/docker/daemon.json,没有这个文件就创建
# 添加以下内容后,重启docker服务:
cat >/etc/docker/daemon.json<<EOF
{
   "registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF

docker部署flink没有kafka插件 docker搭建flink集群_flink_22


# 加载

systemctl reload docker 

# 查看
systemctl status docker containerd

docker部署flink没有kafka插件 docker搭建flink集群_flink_23

 【温馨提示】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

docker部署flink没有kafka插件 docker搭建flink集群_大数据_24


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

docker部署flink没有kafka插件 docker搭建flink集群_flink_25

 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

docker部署flink没有kafka插件 docker搭建flink集群_docker_26

sed -i 's#SystemdCgroup = false#SystemdCgroup = true#g' /etc/containerd/config.toml

docker部署flink没有kafka插件 docker搭建flink集群_大数据_27


# 应用所有更改后,重新启动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之外的别的仓库

docker部署flink没有kafka插件 docker搭建flink集群_ci_28

安装 yum install -y kubernetes-cni

重启containerd后生效 systemctl restart containerd.service

# 设置为开机自启并现在立刻启动服务 --now:立刻启动服务

systemctl start kubelet

systemctl enable --now kubelet

# 查看状态,这里需要等待一段时间再查看服务状态,启动会有点慢
systemctl status kubelet -l

docker部署flink没有kafka插件 docker搭建flink集群_Pod_29

常见问题如下:

1、发现无法启动,更换了k8s yum源

docker部署flink没有kafka插件 docker搭建flink集群_Pod_30

 2 这些错误可能是由于已经存在相同名称的Pod而导致创建失败

docker部署flink没有kafka插件 docker搭建flink集群_大数据_31

  1. 删除已存在的 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

docker部署flink没有kafka插件 docker搭建flink集群_ci_32

3、服务器尚未初始化

docker部署flink没有kafka插件 docker搭建flink集群_大数据_33

 这个错误消息 “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)尚未完全启动或处于不可用状态。

docker部署flink没有kafka插件 docker搭建flink集群_大数据_34

   

 kubectl get pod -n kube-system

docker部署flink没有kafka插件 docker搭建flink集群_Pod_35

查看版本

kubectl version

docker部署flink没有kafka插件 docker搭建flink集群_Pod_36

yum info kubeadm

docker部署flink没有kafka插件 docker搭建flink集群_flink_37

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

docker部署flink没有kafka插件 docker搭建flink集群_flink_38

#--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。

docker部署flink没有kafka插件 docker搭建flink集群_docker_39

例如采用如下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 以指向高可用性方案中的负载均衡器的地址。 

docker部署flink没有kafka插件 docker搭建flink集群_ci_40

配置环境变量

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

docker部署flink没有kafka插件 docker搭建flink集群_ci_41

source /etc/profile

docker部署flink没有kafka插件 docker搭建flink集群_Pod_42

docker部署flink没有kafka插件 docker搭建flink集群_Pod_43

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

docker部署flink没有kafka插件 docker搭建flink集群_ci_44

修改为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

docker部署flink没有kafka插件 docker搭建flink集群_docker_45

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 kubeletsystemctl enable --now kubelet
 systemctl status kubelet在master节点上
kubeadm token create --print-join-command
 可以生成:kubeadm join 192.168.1.244:6443
添加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
kubectl get nodes

docker部署flink没有kafka插件 docker搭建flink集群_大数据_46

#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 nodesscp /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/

docker部署flink没有kafka插件 docker搭建flink集群_ci_47

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

docker部署flink没有kafka插件 docker搭建flink集群_ci_48

 3、编辑 kube-proxy 配置文件,mode 修改成 ipvs

kubectl edit  configmap -n kube-system  kube-proxy

docker部署flink没有kafka插件 docker搭建flink集群_flink_49

 

docker部署flink没有kafka插件 docker搭建flink集群_docker_50

4、重启 kube-proxy

# 先查看
kubectl get pod -n kube-system | grep kube-proxy

docker部署flink没有kafka插件 docker搭建flink集群_Pod_51


# 再delete让它自拉起

kubectl get pod -n kube-system | grep kube-proxy |awk '{system("kubectl delete pod "$1" -n kube-system")}'

docker部署flink没有kafka插件 docker搭建flink集群_大数据_52


# 再查看

kubectl get pod -n kube-system | grep kube-proxy

docker部署flink没有kafka插件 docker搭建flink集群_ci_53

5、查看 ipvs 转发规则

ipvsadm -Ln

docker部署flink没有kafka插件 docker搭建flink集群_flink_54

再次查看 kubectl get nodes

11)集群高可用配置 (非高可用可以忽略)

 配置高可用(HA)Kubernetes 集群实现的两种方案:

  • 使用堆叠(stacked)控制平面节点,其中 etcd 节点与控制平面节点共存(本章使用),架构图如下:

docker部署flink没有kafka插件 docker搭建flink集群_ci_55

这里新增一台机器作为另外一个 master 节点:192.168.0.116 配置跟上面 master 节点一样。只是不需要最后一步初始化了。

 1、修改主机名和配置 hosts 所有节点都统一如下配置:

docker部署flink没有kafka插件 docker搭建flink集群_ci_56

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

docker部署flink没有kafka插件 docker搭建flink集群_flink_57

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 拷贝证书到master2scp /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

docker部署flink没有kafka插件 docker搭建flink集群_大数据_58

 注意: 

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/configkubectl get nodes

docker部署flink没有kafka插件 docker搭建flink集群_大数据_59

 kubectl get pods -A -owide

docker部署flink没有kafka插件 docker搭建flink集群_docker_60

虽然现在已经有两个 master 了,但是对外还是只能有一个入口的,所以还得要一个负载均衡器,如果一个 master 挂了,会自动切到另外一个 master 节点。

 12)部署 Nginx+Keepalived 高可用负载均衡器

参考:

docker部署flink没有kafka插件 docker搭建flink集群_ci_61

1、安装 Nginx 和 Keepalived 

# 在两个master节点上执行
yum install nginx keepalived -y

docker部署flink没有kafka插件 docker搭建flink集群_大数据_62

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 / {
         }
     }
 }
 EOF3、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
     }
 }
 EOFcat > /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
 fiEOF
chmod +x /etc/keepalived/check_nginx.sh
5、启动并设置开机启动
systemctl daemon-reload
systemctl restart nginx && systemctl enable nginx && systemctl status nginx

docker部署flink没有kafka插件 docker搭建flink集群_flink_63

 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

docker部署flink没有kafka插件 docker搭建flink集群_大数据_64

systemctl restart nginx && systemctl enable nginx && systemctl status nginx

docker部署flink没有kafka插件 docker搭建flink集群_flink_65

systemctl restart keepalived && systemctl enable keepalived && systemctl status keepalived

docker部署flink没有kafka插件 docker搭建flink集群_Pod_66

 ip a 查看   暂时VIP没有配置成功,后继持续关注。

curl -k https://cluster-endpoint:16443/version

docker部署flink没有kafka插件 docker搭建flink集群_flink_67

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

docker部署flink没有kafka插件 docker搭建flink集群_ci_68

 创建登录用户

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

https://192.168.1.245:31443/

在页面空白处点击一下,然后输入thisisunsafe后,页面会要求输入上面的token

docker部署flink没有kafka插件 docker搭建flink集群_Pod_69


----------------------------------------------------------------------------------------------------------