LOADING

加载过慢请开启缓存 浏览器默认开启

容器与集群小实训

目录

实训简介

搭建一主两从k8s集群并部署MySQL(可用docker搭建MySQL),构建Python爬虫镜像,定时爬取网页内容并持久化到数据库,把镜像推送到阿里云镜像仓库。

1. MySQL数据库安装

k8s部署MySQL

1. 搭建一主两从k8s集群

1. 服务器配置

需要三台服务器,ip在同一网段,使其可以互相通信,三台服务器可以连接外网,配置不能太低,要满足docker运行要求,建议2核2g,硬盘20g即可,本次实训用的镜像是CentOS 7.9

类似于这种:

img

2. 准备工作

下面这些操作,三台机器都要执行!

关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
关闭SELinux
# 永久关闭
sed -i 's/enforcing/disabled/' /etc/selinux/config
# 临时关闭
setenforce 0
关闭Swap
# 永久关闭
vim /etc/fstab
# 临时关闭
swapoff -a

永久关闭的时候需要注释这一行(带swap)

image-20231220212508717

设置主机名
  • 192.168.154.130: hostnamectl set-hostname k8s-master
  • 192.168.154.131: hostnamectl set-hostname k8s-node1
  • 192.168.154.132: hostnamectl set-hostname k8s-node2

设置完成后:

#192.168.154.130
[root@localhost log]# hostname
k8s-master
#192.168.154.131
[root@localhost log]# hostname
k8s-node1
#192.168.154.130
[root@localhost log]# hostname
k8s-node2
修改host文件
cat >> /etc/hosts << EOF
192.168.154.130 k8s-master
192.168.154.131 k8s-node1
192.168.154.132 k8s-node2
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

3. 开始安装Kubernetes

三台服务器都需要完成以下配置

安装docker

每台电脑都需要安装docker,可执行一下脚本:

#!/bin/bash
sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
sudo yum install -y yum-utils
sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install -y docker-ce docker-ce-cli containerd.io
sudo systemctl start docker
sudo systemctl enable docker

以上脚本执行完之后docker就安装好了

docker

复制以下代码:

image-20231220214325578

然后在中括号下面加上一行代码:

"exec-opts": ["native.cgroupdriver=systemd"]

添加完成后:

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://xxxxx.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
添加K8S的yum源

执行以下代码:

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
安装 kubeletkubeadmkubectl

通过以下命令安装:

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

4. Kubernetes,启动!

启动master

查看版本:

kubeadm version

如图:

image-20231220215728473

然后执行命令启动:

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

注意 --apiserver-advertise-address=192.168.154.130 后面的IP地址需要改成自己mater的IP,然后 --kubernetes-version v1.23.6 的版本注意改成自己K8S的版本。

获取启动信息

查看启动成功的信息

image-20231220222053749

本机执行这些命令(以上面截图的为准):

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
启动两个Slave(node节点执行)

还记得上面需要记录下来的命令吗,就是这行:

kubeadm join 192.168.154.130:6443 --token 7vdvuj.5kvyhzz3ks3tspuy \
    --discovery-token-ca-cert-hash sha256:931aeb772e89b669e2eed1405edbe269a7801d133b63a440cd0efba3b7dbad95 

执行它,查看结果:

image-20231220222935591

master 安装网络插件

我们在master中执行这一行命令:

kubectl get nodes

查看结果:

image-20231220223222109

可以看到两个node成功注册,但是没能达到准备状态,因为 STATUS 仍然是 NotReady 状态,我们需要为 master 安装网络插件:

kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

看到这个代表安装成功(如果没有安装成功,那么需要将文件下载下来,然后将url替换成下载下来的文件):

image-20231220223413034

但是还需要等一下,因为他正在联网下载依赖呢,然后再次查看,就变为 Ready 状态了:

image-20231220231354683

我这个node1节点有问题,我找了许久还是报错,最后我放弃了,因为一个节点不影响MySQL的部署,我还是决定先继续做实验,回头重新安装k8s试试,应该是漏了某个步骤,而正常的应该是这种:

img

如果如上图所示,那你的一主两从集群就部署成功了,中间会遇到各种各样的报错,你可以选择执行某些命令时忽略这些错误项,但是还有一些问题是需要自己解决的。


参考:CentOS7上搭建Kubernetes(K8S)集群并部署nginx(kubeadm方式)_k8s高可用 centos+nginx+kubeadm-CSDN博客

2. 在集群上部署MySQL

1. 创建namespace,把mysql部署在单独的名称空间中

kubectl create namespace dev

2. 创建持久卷PV,用来存储mysql数据文件

1. 定义一个容量大小为1GB的PV,挂载到/nfs/data/01目录
mkdir -p /nfs/data/01
2. 编写mysql-pv.yaml文件内容,要创建的pv对象名称:pv-1gi
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-1gi
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  storageClassName: nfs
  nfs:
    path: /nfs/data/01
    server: 192.168.154.130
3. 创建该PV对象
kubectl create -f mysql-pv.yaml
4. 查看创建结果
kubectl get pv
kubectl describe pv pv-1gi

如图:

屏幕截图 2023-12-20 182529

image-20231220234114072

3. 创建持久卷声明PVC

1. 创建持久卷声明PVC

编写mysql-pvc.yaml文件内容,要创建的pvc对象名称是:mysql-pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
  namespace: dev
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs
2. 创建该PVC对象
kubectl create -f mysql-pvc.yaml
3. 查看创建结果
kubectl get pvc -n dev

可以看到mysql-pvc对象已经和pv-1gi对象绑定上了:

屏幕截图 2023-12-20 182758

4. 创建Secret对象用来保存mysql的root用户密码

1. 设置密码为123456,执行创建命令
kubectl create secret generic mysql-root-password --from-literal=password=123456 -n dev
2. 查看创建结果
kubectl get secret -n dev
kubectl get secret mysql-root-password -n dev -o yaml

屏幕截图 2023-12-20 182855

屏幕截图 2023-12-20 182919

5. 创建service

1. 编辑mysql-svc.yaml文件内容
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: mysql
  name: mysql
  namespace: dev
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - image: mysql:8.0
        name: mysql
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysql-root-password
              key: password 
        ports:
        - containerPort: 3306
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: svc-mysql
  name: svc-mysql
  namespace: dev
spec:
  selector:
    app: mysql
  type: NodePort
  ports:
  - port: 3306
    protocol: TCP
    targetPort: 3306
    nodePort: 31233

service使用NodePort类型,指定暴露的nodePort端口为31233,我们会在宿主机使用navicat客户端对mysql进行访问。

2. 执行创建命令
kubectl create -f mysql-svc.yaml
3. 查看创建结果
kubectl get pod,svc -n dev

屏幕截图 2023-12-20 183128

docker部署MySQL

docker run --name mysql -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 -d mysql

2. MySQL数据库设置远程登录

k8s进入MySQL容器内部

kubectl exec -it mysql-657494c4df-thlqf  /bin/bash -n dev

其中mysql-657494c4df-thlqf是mysql数据库所在pod的pod名称。

docker进入MySQL容器内部

docker exec -it 容器名or容器id /bin/bash

配置root用户远程可连接

ALTER USER root@localhost IDENTIFIED WITH mysql_native_password BY '123456';
ALTER USER root@'%' IDENTIFIED WITH mysql_native_password BY '123456'

创建mydb库并授权给root用户

create database mydb;

grant all privileges on mydb.* to 'root'@'%';
flush privileges;

3. 用navicat连接数据库并完成建表

连接k8s下的MySQL数据库

并建表,插入一条测试数据:

create table test0918(col1 varchar(100));
insert into test0918 values('aaa');

然后新建一个后续实验用到的表:

CREATE TABLE product_info(
product_name varchar (1000)
, supplier varchar (1000)
, supplier_web varchar (1000)
, product_desc varchar (1000)
,product_img varchar (1000)
, product_price varchar (1000)
, addr varchar (1000)
, mailing_ins varchar (1000))

屏幕截图 2023-12-18 024723

(此处找不到原图了,只得先用一张docker最终实验测试成功的截图)

连接docker下的MySQL数据库

建表语句同上

image-20231221002309917

4. 制作dockerfile并创建镜像,运行容器

镜像中需要包含python环境,并且包含爬虫的数据解析包,并包含脚本的自动调度命令。

1. 创建定时任务的Dockerfile

# 使用阿里云的CentOS 7镜像作为基础镜像
FROM centos:7

# 配置阿里云的yum源
RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
RUN curl -o /etc/yum.repos.d/epel.repo https://mirrors.aliyun.com/repo/epel-7.repo
RUN yum makecache fast

# 安装cronie和更新系统
RUN yum -y install cronie.x86_64 && \
    yum -y update

# 安装Python开发相关的工具
RUN yum install python3-devel python3-pip -y

# 安装Python依赖包,注意将 "pip3 install urllib" 替换为 "pip3 install urllib3"
RUN pip3 install -i https://pypi.douban.com/simple pymysql urllib3 beautifulsoup4

# 复制脚本和Python文件到容器内
COPY ./script.sh /script.sh
COPY ./mysql.py /mysql.py

# 添加执行权限
RUN chmod +x /script.sh
RUN chmod +x /mysql.py

# 设置定时任务
CMD crond -n

2. 编写script.sh和mysql.py

script.sh:

python3 /mysql.py >> /var/log/cron.log 2>&1

mysql.py:

注意mysql.py中的数据库端口,这里docker中和k8s中并不一样

#!/usr/bin/env python
# coding: utf-8

# In[1]:



import urllib.request
from time import sleep
from bs4 import BeautifulSoup as bs
from urllib.parse import urljoin
import pymysql


# In[2]:


headers = {
    'User-Agent': 'Mozilla/6.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36'
}


# In[3]:


def get_info(page):
    url='https://www.cnhnb.com/p/mianfen-0-0-0-0-{}/'.format(page)
    req = urllib.request.Request(url, headers=headers)
    html = urllib.request.urlopen(req)
    soup = bs(html.read(), 'html.parser')
    lu = soup.find_all('div',class_='show-ctn')
    product_all=[]
    for i in lu:
        product_name=i.find('h2').get_text()#产品名称
        supplier=i.find("a").get_text()#供应商
        supplier_web=i.find("a").attrs['href']#供应商网址
        product_desc=i.find('div',class_='shop-image').img.attrs['alt']#产品介绍
        product_img=i.find('div',class_='shop-image').img.attrs['src']#产品图片
        product_price=str(i.find('div',class_='shops-price').get_text()).strip().replace('\n','').replace(' ','')#产品价格
        addr=str(i.find('div',class_='r-shop-btm').get_text())#发货地
        mailing_ins=str(i.find('div',class_='cw-tags').get_text()).strip().replace('\n','').replace(' ','')#邮寄说明
        product=[product_name,supplier,supplier_web,product_desc,product_img,product_price,addr,mailing_ins]
        product_all.append(product)
    return product_all


# In[12]:


def save_mysql(all_data):
    conn = pymysql.connect(host='192.168.154.130', user='root', port=31233, password='123456', db='mydb', charset='utf8')
    # 注意不要忘记换host
    curson = conn.cursor()
    # 创建表sql语句
    #ctablesql = 'CREATE TABLE product_info(product_name varchar (1000), supplier varchar (1000), supplier_web varchar (1000), product_desc varchar (1000),product_img varchar (1000), product_price varchar (1000), addr varchar (1000), mailing_ins varchar (1000))'
    #curson.execute(ctablesql)
    # 插入数据SQL语句
    insertsql = 'insert into product_info(product_name,supplier,supplier_web,product_desc,product_img,product_price,addr,mailing_ins) value (%s,%s,%s,%s,%s,%s,%s,%s)'
    for data in all_data:
        data = tuple(data)
        curson.execute(insertsql, data)
    conn.commit()


# In[13]:


if __name__ == '__main__':
    for i in range(1,89):
        all_data=get_info(i)
        save_mysql(all_data)


# In[ ]:

3. 利用Dockerfile创建镜像

docker build -t docker-crond .

屏幕截图 2023-12-18 024855

4. 运行并进入容器内部,配置定时任务(若crond 未启动,直接运行此命令)

docker run -it docker-crond /bin/bash
crond
crontab -e

添加如下内容:

*/5 * * * * /script.sh >> /var/log/cron.log 2>&1

2>&1是一个重定向操作符,用于将标准错误(文件描述符2)重定向到标准输出(文件描述符1)

验证:

crontab -l

屏幕截图 2023-12-18 024800

5. 查看数据库结果

脚本运行起来之后,就可以通过navicat查看数据了,脚本调度调度失败,相关的失败日志信息就会写入到/var/log/cron.log中。

k8s数据库结果:

image-20231221004706038

docker数据库结果:

屏幕截图 2023-12-20 191548

5. 构建镜像并推送到阿里云镜像仓库

1. 构建镜像

先停止容器,停止前记住容器id:

docker ps
docker stop 容器id

屏幕截图 2023-12-18 024628

docker commit 容器id 镜像名:版本号

屏幕截图 2023-12-18 024613

2. 推送到阿里云镜像仓库

1. 准备工作

1. 找到阿里云容器镜像服务ACR,并打开控制台:

image-20231221005222487

2. 找到个人实例,先创建命名空间:

image-20231221005513145

3. 在该命名空间下创建一个镜像仓库my-docker-crond,注意地域:

image-20231221100311796

剩下的根据操作指南操作。

2. 登录阿里云Docker Registry

image-20231221011604426

image-20231221011719764

3. tagandpush

image-20231221100619023

屏幕截图 2023-12-18 024508

4. 仓库验证

image-20231221100517948

实训总结

这次实训的重点在于搭建一主两从k8s集群,中间我遇到了各种各样的错误,我还是不能找到一个百分百搭建成功的方法,说实话,有点挫败感,不过我依然从中学到了很多知识,了解了k8s的基本架构,更重要的是,我锻炼了解决实际问题的能力。

载入天数...载入时分秒...