Flink on k8s 环境搭建(一)

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而导致创建失败

  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

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. [email protected]:/etc/kubernetes/

scp /etc/kubernetes/pki/ca.* [email protected]:/etc/kubernetes/pki/

scp /etc/kubernetes/pki/sa.* [email protected]:/etc/kubernetes/pki/

scp /etc/kubernetes/pki/front-proxy-ca.* [email protected]:/etc/kubernetes/pki/

在master2上 mkdir -p /etc/kubernetes/pki/etcd

scp /etc/kubernetes/pki/etcd/ca.* [email protected]:/etc/kubernetes/pki/etcd/

scp /etc/kubernetes/pki/etcd/ca.* [email protected]:/etc/kubernetes/pki/etcd/

scp /etc/kubernetes/admin.conf [email protected]:/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 {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   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 {
     [email protected]
     [email protected]
     [email protected]
   }
   notification_email_from [email protected]
   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

https://192.168.1.245:31443/

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


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

猜你喜欢

转载自blog.csdn.net/wangqiaowq/article/details/131800658
今日推荐