• 【谷粒商城 - k8s、devOps专栏】


    一、K8s快速入门

    其他项目的K8S笔记:https://blog.csdn.net/hancoder/category_11140481.html

    1)简介

    kubernetes简称k8s。是用于自动部署,扩展和管理容器化应用程序的开源系统。

    部署方式的进化:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7TFGxran-1633940167403)(https://d33wubrfki0l68.cloudfront.net/26a177ede4d7b032362289c6fccd448fc4a91174/eb693/images/docs/container_evolution.svg)]

    传统部署时代:

    早期,各个组织机构在物理服务器上运行应用程序。无法为物理服务器中的应用程序定义资源边界,这会导致资源分配问题。 例如,如果在物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况, 结果可能导致其他应用程序的性能下降。 一种解决方案是在不同的物理服务器上运行每个应用程序,但是由于资源利用不足而无法扩展, 并且维护许多物理服务器的成本很高。

    虚拟化部署时代:

    作为解决方案,引入了虚拟化。虚拟化技术允许你在单个物理服务器的 CPU 上运行多个虚拟机(VM)。 虚拟化允许应用程序在 VM 之间隔离,并提供一定程度的安全,因为一个应用程序的信息 不能被另一应用程序随意访问。

    虚拟化技术能够更好地利用物理服务器上的资源,并且因为可轻松地添加或更新应用程序 而可以实现更好的可伸缩性,降低硬件成本等等。

    每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

    容器部署时代:

    容器类似于 VM,但是它们具有被放宽的隔离属性,可以在应用程序之间共享操作系统(OS)。 因此,容器被认为是轻量级的。容器与 VM 类似,具有自己的文件系统、CPU、内存、进程空间等。 由于它们与基础架构分离,因此可以跨云和 OS 发行版本进行移植。

    容器因具有许多优势而变得流行起来。下面列出的是容器的一些好处:

    • 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
    • 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),支持可靠且频繁的 容器镜像构建和部署。
    • 关注开发与运维的分离:在构建/发布时而不是在部署时创建应用程序容器镜像, 从而将应用程序与基础架构分离。
    • 可观察性不仅可以显示操作系统级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
    • 跨开发、测试和生产的环境一致性:在便携式计算机上与在云中相同地运行。
    • 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
    • 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
    • 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
    • 资源隔离:可预测的应用程序性能。
    • 资源利用:高效率和高密度。

    ok不多介绍了,还是好好听课后看我k8s的专栏吧

    2)架构

    参考其他笔记:https://blog.csdn.net/hancoder/category_11140481.html

    (2)master节点架构

    kube-apiserver

    • 对外暴露K8S的、接口,是外界进行资源操作的唯一入口
    • 提供认证、授权、访问控制、API注册和发现等机制

    etcd

    • 是兼具一致性和高可用性的键值数据库,可以作为保存Kubernetes所有集群数据的后台数据库。
    • Kubernetes集群的数据库通常需要有个备份计划

    kube-scheduler

    • 主节点上的组件,该组件监视那些新创建的未指定运行节点的Pod,并选择节点让Pod在上面运行。
    • 所有对k8s的集群操作,都必须经过主节点进行调度

    kube-controller-manager

    • 在主节点上运行控制器的组件
    • 这些控制器包括
      • 节点控制器(NodeController):负责在节点出现故障时进行通知和响应。
      • 副本控制器(ReplicationController):负责为系统中的每个副本控制器对象维护正确数量的Pod.
      • 端点控制器(EndpointsController):填充端点(Endpoints)对象(即加入service与Pod)
      • 服务帐户和令牌控制器(Service Account&Token Controllers).为新的命名空间创建默认帐户和API访可令牌
    (3)Node节点架构

    kubelet

    • 一个在集群中每个Node节点上运行的代理。它保证容器都运行在Pod中。
    • 负责维护容器的生命周期,同时也负责Volume(CSI)和网络(CNI)的管理

    kube-proxy

    • 负责为提供cluster内部的服务发现和负载均衡

    容器运行环境(Container Runtime)

    • 容器运行环境是负责运行容器的软件。
    • Kubernetes支持多个容器运行环境.Docker、containerd、cri-o、rktlet以及任何实现Kubernetes CRI(容器运行环境接口)。

    fluentd

    • 是一个守护进程,它有助于提供集群层面日志集群层面的日志

    3)核心组件

    可以参考别的项目的笔记,不在赘述:

    https://blog.csdn.net/hancoder/article/details/117969869

    https://blog.csdn.net/hancoder/article/details/118053399

    4)快速体验

    (1)安装minikube
    https://github.com/kubernetes/minikube/releases
    下载minikuber-windows-amd64.exe 改名为minikube.exe
    打开virtualBox,打开cmd
    运行
    minikube start --vm-driver=virtualbox --registry-mirror=https://registry.docker-cn.com
    等待20分钟即可。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    (2)体验nginx部署升级
    # 提交一个nginx deployment
    kubectl apply -f https://k8s.io/examples/application/deployment.yaml
    # 升级 nginx deployment
    kubectl apply -f https://k8s.io/examples/application/deployment-update.yaml
    # 扩容 nginx deployment
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二、K8s集群安装

    更详细的安装在别的文章里有https://blog.csdn.net/hancoder/article/details/118053239

    看着安装即可,别问我白嫖该文档,不是谷粒的学习笔记

    1)kubeadm

    kubeadm是官方社区推出的一个用于快速部署kuberneters集群的工具。
    这个工具能通过两条指令完成一个kuberneters集群的部署

    创建一个master节点

    $ kuberneters init
    1
    
    • 1
    • 2

    将一个node节点加入到当前集群中

    $ kubeadm join 
    1
    
    • 1
    • 2

    2)前置要求

    一台或多台机器,操作系统Centos7.x-86_x64
    硬件配置:2GB或更多RAM,2个CPU或更多CPU,硬盘30GB或更多
    集群中所有的机器之间网络互通
    可以访问外网,需要拉取镜像
    禁止Swap分区

    3)部署步骤

    1. 在所有的节点上安装Docker和kubeadm
    2. 部署Kubernetes Master
    3. 部署容器网络插件
    4. 部署Kubernetes Node,将节点加入Kubernetes集群中
    5. 部署DashBoard web页面,可视化查看Kubernetes资源
    12345
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    image-20200503144120720

    4)环境准备

    (1)准备工作
    • 使用vagrant快速创建三个虚拟机。虚拟机启动前先设置virtualbox的主机网络。现在全部统一为192.168.56.1,以后所有虚拟机都是56.x的ip地址。

    image-20200503175351320

    • 在全局设定中,找到一个空间比较大的磁盘用用来存放镜像。

    image-20200503180202640

    网卡1是NAT,用于虚拟机与本机访问互联网。网卡2是仅主机网络,虚拟机内部共享的虚拟网络

    (2)启动三个虚拟机

    使用我们提供的vagrant文件,复制到非中文无空格目录下,运行vagrant up启动三个虚拟机。其实vagrant完全可以一键部署全部K8s集群
    https://github.com/rootsongjc/kubernetes-vagrant-centos-cluster
    http://github.com/davidkbainbridge/k8s-playground

    下面是vagrantfile,使用它来创建三个虚拟机,分别为k8s-node1,k8s-node2和k8s-node3.

    Vagrant.configure("2") do |config|
    	# 遍历
       (1..3).each do |i|
            config.vm.define "k8s-node#{i}" do |node|
                # 设置虚拟机的Box
                node.vm.box = "centos/7"
    
                # 设置虚拟机的主机名
                node.vm.hostname="k8s-node#{i}"
    
                # 设置虚拟机的IP  100 101 102
                node.vm.network "private_network", ip: "192.168.56.#{99+i}", netmask: "255.255.255.0"
    
                # 设置主机与虚拟机的共享目录
                # node.vm.synced_folder "~/Documents/vagrant/share", "/home/vagrant/share"
    
                # VirtaulBox相关配置
                node.vm.provider "virtualbox" do |v|
                    # 设置虚拟机的名称
                    v.name = "k8s-node#{i}"
                    # 设置虚拟机的内存大小
                    v.memory = 4096
                    # 设置虚拟机的CPU个数
                    v.cpus = 4
                end
            end
       end
    end
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 进入到三个虚拟机,开启root的密码访问权限
    vagrant ssh xxx进入到系统后
    # vagrant ssh k8s-node1
    su root 密码为vagrant
    
    vi /etc/ssh/sshd_config
    
    修改
    PermitRootLogin yes 
    PasswordAuthentication yes
    
    所有的虚拟机设为4核4G
    1234567891011
    service sshd restart
    192.68.56.100:22
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    网络配置

    关于在"网络地址转换"的连接方式下,三个节点的eth0,IP地址相同的问题。

    **问题描述:**查看k8s-node1的路由表:

    # 查看默认的网卡
    [root@k8s-node1 ~]# ip route show
    default via 10.0.2.2 dev eth0 proto dhcp metric 100  # 默认使用eth0
    
    10.0.2.0/24 dev eth0 proto kernel scope link src 10.0.2.15 metric 100  # 网关和ip
    
    192.168.56.0/24 dev eth1 proto kernel scope link src 192.168.56.100 metric 101 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    能够看到路由表中记录的是,通过端口eth0进行数据包的收发。

    分别查看k8s-node1,k8s-node2和k8s-node3的eth0所绑定的IP地址,发现它们都是相同的,全都是10.0.2.15,这些地址是供kubernetes集群通信用的;eth1上的IP地址,是通远程管理使用的。

    [root@k8s-node1 ~]# ip addr
    ...
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 52:54:00:8a:fe:e6 brd ff:ff:ff:ff:ff:ff
        # ip
        inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
           valid_lft 84418sec preferred_lft 84418sec
        inet6 fe80::5054:ff:fe8a:fee6/64 scope link 
           valid_lft forever preferred_lft forever
    3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 08:00:27:a3:ca:c0 brd ff:ff:ff:ff:ff:ff
        # ip
        inet 192.168.56.100/24 brd 192.168.56.255 scope global noprefixroute eth1
           valid_lft forever preferred_lft forever
        inet6 fe80::a00:27ff:fea3:cac0/64 scope link 
           valid_lft forever preferred_lft forever
    [root@k8s-node1 ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    **原因分析:**这是因为它们使用是端口转发规则,使用同一个地址,通过不同的端口来区分。但是这种端口转发规则在以后的使用中会产生很多不必要的问题,所以需要修改为NAT网络类型。

    下面是临时解决方案:

    image-20200503184536343

    终极解决方法:

    • 选择三个节点,然后执行“管理”->“全局设定”->“网络”,添加一个NAT网络。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-endXaW6I-1669546538221)(https://fermhan.oss-cn-qingdao.aliyuncs.com/guli/image-20200503184919936.png)]

    • 分别修改每台设备的网络类型,并刷新重新生成MAC地址。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cRTL7kUB-1669546538222)(https://fermhan.oss-cn-qingdao.aliyuncs.com/guli/image-20200503185344246.png)]

    刷新一下MAC地址

    1网络是集群交互,2网络是宿主交互

    • 再次查看三个节点的IP
    [root@k8s-node1 ~]# ip addr
    。。。
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 08:00:27:7e:dd:f5 brd ff:ff:ff:ff:ff:ff
        # 10.0.2.15
        inet 10.0.2.15/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
           valid_lft 86357sec preferred_lft 86357sec
        inet6 fe80::a00:27ff:fe7e:ddf5/64 scope link
           valid_lft forever preferred_lft 
    ===================================================
    [root@k8s-node2 ~]# ip addr
    。。。
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 08:00:27:86:c0:a2 brd ff:ff:ff:ff:ff:ff
        # 10.0.2.5
        inet 10.0.2.5/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
           valid_lft 527sec preferred_lft 527sec
        inet6 fe80::a00:27ff:fe86:c0a2/64 scope link
           valid_lft forever preferred_lft forever
    
    =================================================
    [root@k8s-node3 ~]# ip addr
    。。。
    2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 08:00:27:a1:94:f9 brd ff:ff:ff:ff:ff:ff
        # 10.0.2.6
        inet 10.0.2.6/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
           valid_lft 518sec preferred_lft 518sec
        inet6 fe80::a00:27ff:fea1:94f9/64 scope link
           valid_lft forever preferred_lft forever
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    技巧:MobaXterm上面的Multi-exec模式了解一下

    (3)设置Linux环境(三个节点都执行)
    • 关闭防火墙
    systemctl stop firewalld
    systemctl disable firewalld
    
    • 1
    • 2
    • 关闭seLinux
    # linux默认的安全策略
    sed -i 's/enforcing/disabled/' /etc/selinux/config
    setenforce 0
    
    • 1
    • 2
    • 3
    • 关闭swap
    swapoff -a #临时关闭
    sed -ri 's/.*swap.*/#&/' /etc/fstab #永久关闭
    free -g #验证,swap必须为0
    
    • 1
    • 2
    • 3
    • 添加主机名与IP对应关系:

    查看主机名:

    hostname
    
    • 1

    如果主机名不正确,可以通过“hostnamectl set-hostname :指定新的hostname”命令来进行修改。

    vi /etc/hosts
    10.0.2.15 k8s-node1
    10.0.2.5 k8s-node2
    10.0.2.6 k8s-node3
    
    • 1
    • 2
    • 3
    • 4

    差不多就这个意思,我的ip可能在后来也改了

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

    cat > /etc/sysctl.d/k8s.conf <<EOF
    
    net.bridge.bridge-nf-call-ip6tables = 1
    
    net.bridge.bridge-nf-call-iptables = 1
    
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    应用规则:

    sysctl --system
    
    • 1

    疑难问题:遇见提示是只读的文件系统,运行如下命令

    mount -o remount rw /
    
    • 1
    • date 查看时间(可选)
    yum -y install ntpupdate
    
    ntpupdate time.window.com #同步最新时间
    
    • 1
    • 2
    • 3

    5)所有节点安装docker、kubeadm、kubelet、kubectl

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

    (1)安装Docker

    1、卸载之前的docker

    sudo yum remove docker \
                      docker-client \
                      docker-client-latest \
                      docker-common \
                      docker-latest \
                      docker-latest-logrotate \
                      docker-logrotate \
                      docker-engine
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    2、安装Docker -CE

    sudo yum install -y yum-utils \
    device-mapper-persistent-data \
    lvm2
    # 设置docker repo的yum位置
    sudo yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
        
        # 安装docker,docker-cli
    sudo yum -y install docker-ce docker-ce-cli containerd.io   
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3、配置docker加速

    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://ke9h1pt4.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4、启动Docker && 设置docker开机启动

    systemctl enable docker
    
    • 1

    基础环境准备好,可以给三个虚拟机备份一下;

    image-20200503192940651

    (2)添加阿里与Yum源
    cat <<EOF > /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    更多详情见: https://developer.aliyun.com/mirror/kubernetes

    (3)安装kubeadm,kubelet和kubectl
    yum list|grep kube
    
    • 1

    安装

    yum install -y kubelet-1.17.3 kubeadm-1.17.3 kubectl-1.17.3
    
    • 1

    开机启动

    systemctl enable kubelet && systemctl start kubelet
    
    • 1

    查看kubelet的状态:

    systemctl status kubelet
    
    • 1

    查看kubelet版本:

    [root@k8s-node2 ~]# kubelet --version
    Kubernetes v1.17.3
    
    • 1
    • 2

    6)部署k8s-master

    (1)master节点初始化

    在Master节点上,创建并执行master_images.sh

    #!/bin/bash
    
    images=(
    	kube-apiserver:v1.17.3
        kube-proxy:v1.17.3
    	kube-controller-manager:v1.17.3
    	kube-scheduler:v1.17.3
    	coredns:1.6.5
    	etcd:3.4.3-0
        pause:3.1
    )
    
    for imageName in ${images[@]} ; do
        docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName
    #   docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/$imageName  k8s.gcr.io/$imageName
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    查看100的内部通信端口

    2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 08:00:27:7e:dd:f5 brd ff:ff:ff:ff:ff:ff
        inet 10.0.2.4/24 brd 10.0.2.255 scope global noprefixroute dynamic eth0
           valid_lft 512sec preferred_lft 512sec
        inet6 fe80::a00:27ff:fe7e:ddf5/64 scope link
           valid_lft forever preferred_lft forever
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    初始化kubeadm
    kubeadm init \
    --apiserver-advertise-address=10.0.2.7 \
    --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
    --kubernetes-version   v1.17.3 \
    --service-cidr=10.96.0.0/16  \
    --pod-network-cidr=10.244.0.0/16
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注:

    • –apiserver-advertise-address=10.0.2.4 :这里的IP地址是master主机的地址,为上面的eth0网卡的地址;
    • pod-network-cidr:pod之间的访问

    执行结果:

    [root@k8s-node1 opt]# kubeadm init \
    > --apiserver-advertise-address=10.0.2.15 \
    > --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
    > --kubernetes-version   v1.17.3 \
    > --service-cidr=10.96.0.0/16  \
    > --pod-network-cidr=10.244.0.0/16
    W0503 14:07:12.594252   10124 configset.go:202] WARNING: kubeadm cannot validate component configs for API groups [kubelet.config.k8s.io kubeproxy.config.k8s.io]
    [init] Using Kubernetes version: v1.17.3
    [preflight] Running pre-flight checks
            [WARNING IsDockerSystemdCheck]: detected "cgroupfs" as the Docker cgroup driver. The recommended driver is "systemd". Please follow the guide at https://kubernetes.io/docs/setup/cri/
    [preflight] Pulling images required for setting up a Kubernetes cluster
    [preflight] This might take a minute or two, depending on the speed of your internet connection
    [preflight] You can also perform this action in beforehand using 'kubeadm config images pull'
    [kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
    [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
    [kubelet-start] Starting the kubelet
    。。。。。。。。。。。。。。。
    [kubelet-finalize] Updating "/etc/kubernetes/kubelet.conf" to point to a rotatable kubelet client certificate and key
    [addons] Applied essential addon: CoreDNS
    [addons] Applied essential addon: kube-proxy
    #表示kubernetes已经初始化成功了
    Your Kubernetes control-plane has initialized successfully!
    
    To start using your cluster, you need to run the following as a regular user:
    
      mkdir -p $HOME/.kube
      sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
    You should now deploy a pod network to the cluster.
    Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
      https://kubernetes.io/docs/concepts/cluster-administration/addons/
    
    Then you can join any number of worker nodes by running the following on each as root:
    
    kubeadm join 10.0.2.15:6443 --token sg47f3.4asffoi6ijb8ljhq \
        --discovery-token-ca-cert-hash sha256:81fccdd29970cbc1b7dc7f171ac0234d53825bdf9b05428fc9e6767436991bfb 
    # 上面他也说了如何加入新结点
    # 如果过期了还没有加入,百度 kubeadm token过期
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    由于默认拉取镜像地址k8s.cr.io国内无法访问,这里指定阿里云仓库地址。可以手动按照我们的images.sh先拉取镜像。

    地址变为:registry.aliyuncs.com/googole_containers也可以。

    科普:无类别域间路由(Classless Inter-Domain Routing 、CIDR)是一个用于给用户分配IP地址以及在互联网上有效第路由IP数据包的对IP地址进行归类的方法。

    拉取可能失败,需要下载镜像。

    运行完成提前复制:加入集群的令牌。

    (2)测试Kubectl(主节点执行)
    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
    • 1
    • 2
    • 3

    详细部署文档:https://kubernetes.io/docs/concepts/cluster-administration/addons/

     kubectl get nodes #获取所有节点
     # 目前Master状态为notready。等待网络加入完成即可。
     
     
     journalctl -u kubelet #查看kubelet日志
    12345
    kubeadm join 10.0.2.4:6443 --token bt3hkp.yxnpzsgji4a6edy7 \
        --discovery-token-ca-cert-hash sha256:64949994a89c53e627d68b115125ff753bfe6ff72a26eb561bdc30f32837415a
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    7)安装POD网络插件(CNI)

    在master节点上执行按照POD网络插件

    kubectl apply -f \
    https://raw.githubusercontent.com/coreos/flanne/master/Documentation/kube-flannel.yml
    12
    
    • 1
    • 2
    • 3

    以上地址可能被墙,可以直接获取本地已经下载的flannel.yml运行即可(https://blog.csdn.net/lxm1720161656/article/details/106436252 可以去下载),如:

    [root@k8s-node1 k8s]# kubectl apply -f  kube-flannel.yml    
    podsecuritypolicy.policy/psp.flannel.unprivileged created
    clusterrole.rbac.authorization.k8s.io/flannel created
    clusterrolebinding.rbac.authorization.k8s.io/flannel created
    serviceaccount/flannel created
    configmap/kube-flannel-cfg created
    daemonset.apps/kube-flannel-ds-amd64 created
    daemonset.apps/kube-flannel-ds-arm64 created
    daemonset.apps/kube-flannel-ds-arm created
    daemonset.apps/kube-flannel-ds-ppc64le created
    daemonset.apps/kube-flannel-ds-s390x created
    [root@k8s-node1 k8s]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    同时flannel.yml中指定的images访问不到可以去docker hub找一个wget yml地址

    vi 修改yml 所有amd64的地址修改了即可
    等待大约3分钟
    kubectl get pods -n kube-system 查看指定名称空间的pods
    kubectl get pods -all-namespace 查看所有名称空间的pods
    
    $ ip link set cni0 down 如果网络出现问题,关闭cni0,重启虚拟机继续测试
    执行watch kubectl get pod -n kube-system -o wide 监控pod进度
    等待3-10分钟,完全都是running以后继续
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    查看命名空间:

    [root@k8s-node1 k8s]# kubectl get ns
    NAME              STATUS   AGE
    default           Active   30m
    kube-node-lease   Active   30m
    kube-public       Active   30m
    kube-system       Active   30m
    [root@k8s-node1 k8s]#
    1234567
    [root@k8s-node1 k8s]# kubectl get pods --all-namespaces       
    NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
    kube-system   coredns-546565776c-9sbmk            0/1     Pending   0          31m
    kube-system   coredns-546565776c-t68mr            0/1     Pending   0          31m
    kube-system   etcd-k8s-node1                      1/1     Running   0          31m
    kube-system   kube-apiserver-k8s-node1            1/1     Running   0          31m
    kube-system   kube-controller-manager-k8s-node1   1/1     Running   0          31m
    kube-system   kube-flannel-ds-amd64-6xwth         1/1     Running   0          2m50s
    kube-system   kube-proxy-sz2vz                    1/1     Running   0          31m
    kube-system   kube-scheduler-k8s-node1            1/1     Running   0          31m
    [root@k8s-node1 k8s]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    查看master上的节点信息:

    [root@k8s-node1 k8s]# kubectl get nodes
    NAME        STATUS   ROLES    AGE   VERSION
    k8s-node1   Ready    master   34m   v1.17.3   #status为ready才能够执行下面的命令
    [root@k8s-node1 k8s]#
    
    • 1
    • 2
    • 3
    • 4

    最后再次执行,并且分别在“k8s-node2”和“k8s-node3”上也执行这里命令:

    kubeadm join 10.0.2.4:6443 --token bt3hkp.yxnpzsgji4a6edy7 \
        --discovery-token-ca-cert-hash sha256:64949994a89c53e627d68b115125ff753bfe6ff72a26eb561bdc30f32837415a
    12
    [root@k8s-node1 opt]# kubectl get nodes;
    NAME        STATUS     ROLES    AGE   VERSION
    k8s-node1   Ready      master   47m   v1.17.3
    k8s-node2   NotReady   <none>   75s   v1.17.3
    k8s-node3   NotReady   <none>   76s   v1.17.3
    [root@k8s-node1 opt]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    监控pod进度

    # 在master执行
    watch kubectl get pod -n kube-system -o wide
    
    • 1
    • 2

    等到所有的status都变为running状态后,再次查看节点信息:

    [root@k8s-node1 ~]#  kubectl get nodes;                         
    NAME        STATUS   ROLES    AGE     VERSION
    k8s-node1   Ready    master   3h50m   v1.17.3
    k8s-node2   Ready    <none>   3h3m    v1.17.3
    k8s-node3   Ready    <none>   3h3m    v1.17.3
    [root@k8s-node1 ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    8)加入kubenetes的Node节点

    在node节点中执行,向集群中添加新的节点,执行在kubeadm init 输出的kubeadm join命令;
    确保node节点成功:
    token过期怎么办
    kubeadm token create --print-join-command

    9)入门操作kubernetes集群

    1、在主节点上部署一个tomcat
    kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8
    
    • 1

    获取所有的资源:

    [root@k8s-node1 k8s]# kubectl get all
    NAME                           READY   STATUS              RESTARTS   AGE
    pod/tomcat6-7b84fb5fdc-cfd8g   0/1     ContainerCreating   0          41s
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   70m
    
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/tomcat6   0/1     1            0           41s
    
    NAME                                 DESIRED   CURRENT   READY   AGE
    replicaset.apps/tomcat6-7b84fb5fdc   1         1         0       41s
    [root@k8s-node1 k8s]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    kubectl get pods -o wide 可以获取到tomcat部署信息,能够看到它被部署到了k8s-node3上了

    [root@k8s-node1 k8s]# kubectl get all -o wide
    NAME                           READY   STATUS              RESTARTS   AGE   IP       NODE        NOMINATED NODE   READINESS GATES
    pod/tomcat6-5f7ccf4cb9-xhrr9   0/1     ContainerCreating   0          77s   <none>   k8s-node3   <none>           <none>
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE   SELECTOR
    service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   68m   <none>
    
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES               SELECTOR
    deployment.apps/tomcat6   0/1     1            0           77s   tomcat       tomcat:6.0.53-jre8   app=tomcat6
    
    NAME                                 DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES               SELECTOR
    replicaset.apps/tomcat6-5f7ccf4cb9   1         1         0       77s   tomcat       tomcat:6.0.53-jre8   app=tomcat6,pod-template-hash=5f7ccf4cb9
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    查看node3节点上,下载了哪些镜像:

    [root@k8s-node3 k8s]# docker images
    REPOSITORY                                                       TAG             IMAGE ID       CREATED         SIZE
    registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy   v1.17.3         ae853e93800d   14 months ago   116MB
    quay.io/coreos/flannel                                           v0.11.0-amd64   ff281650a721   2 years ago     52.6MB
    registry.cn-hangzhou.aliyuncs.com/google_containers/pause        3.1             da86e6ba6ca1   3 years ago     742kB
    tomcat                                                           6.0.53-jre8     49ab0583115a   3 years ago     290MB
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    查看Node3节点上,正在运行的容器:

    [root@k8s-node3 k8s]# docker ps
    CONTAINER ID   IMAGE                                                            COMMAND                  CREATED              STATUS              PORTS     NAMES
    8a197fa41dd9   tomcat                                                           "catalina.sh run"        About a minute ago   Up About a minute             k8s_tomcat_tomcat6-5f7ccf4cb9-xhrr9_default_81f186a8-4805-4bbb-8d77-3142269942ed_0
    4074d0d63a88   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1    "/pause"                 2 minutes ago        Up 2 minutes                  k8s_POD_tomcat6-5f7ccf4cb9-xhrr9_default_81f186a8-4805-4bbb-8d77-3142269942ed_0
    db3faf3a280d   ff281650a721                                                     "/opt/bin/flanneld -…"   29 minutes ago       Up 29 minutes                 k8s_kube-flannel_kube-flannel-ds-amd64-vcktd_kube-system_31ca3556-d6c3-48b2-b393-35ff7d89a078_0
    be461b54cb4b   registry.cn-hangzhou.aliyuncs.com/google_containers/kube-proxy   "/usr/local/bin/kube…"   30 minutes ago       Up 30 minutes                 k8s_kube-proxy_kube-proxy-ptq2t_kube-system_0e1f7df3-7204-481d-bf15-4b0e09cf0c81_0
    88d1ab87f400   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1    "/pause"                 31 minutes ago       Up 31 minutes                 k8s_POD_kube-flannel-ds-amd64-vcktd_kube-system_31ca3556-d6c3-48b2-b393-35ff7d89a078_0
    52be28610a02   registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.1    "/pause"                 31 minutes ago       Up 31 minutes                 k8s_POD_kube-proxy-ptq2t_kube-system_0e1f7df3-7204-481d-bf15-4b0e09cf0c81_0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在node1上执行:

    [root@k8s-node1 k8s]# kubectl get pods
    NAME                       READY   STATUS    RESTARTS   AGE
    tomcat6-7b84fb5fdc-cfd8g   1/1     Running   0          5m35s
    
    [root@k8s-node1 k8s]# kubectl get pods --all-namespaces
    NAMESPACE     NAME                                READY   STATUS    RESTARTS   AGE
    default       tomcat6-7b84fb5fdc-cfd8g            1/1     Running   0          163m
    kube-system   coredns-546565776c-9sbmk            1/1     Running   0          3h52m
    kube-system   coredns-546565776c-t68mr            1/1     Running   0          3h52m
    kube-system   etcd-k8s-node1                      1/1     Running   0          3h52m
    kube-system   kube-apiserver-k8s-node1            1/1     Running   0          3h52m
    kube-system   kube-controller-manager-k8s-node1   1/1     Running   0          3h52m
    kube-system   kube-flannel-ds-amd64-5xs5j         1/1     Running   0          3h6m
    kube-system   kube-flannel-ds-amd64-6xwth         1/1     Running   0          3h24m
    kube-system   kube-flannel-ds-amd64-fvnvx         1/1     Running   0          3h6m
    kube-system   kube-proxy-7tkvl                    1/1     Running   0          3h6m
    kube-system   kube-proxy-mvlnk                    1/1     Running   0          3h6m
    kube-system   kube-proxy-sz2vz                    1/1     Running   0          3h52m
    kube-system   kube-scheduler-k8s-node1            1/1     Running   0          3h52m
    [root@k8s-node1 ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    从前面看到tomcat部署在Node3上,现在模拟因为各种原因宕机的情况,将node3关闭电源,观察情况。

    docker stop执行的时候,docker ps发现又有新的容器了,这是k8s又新建了,所以选择关机node3

    [root@k8s-node1 k8s]# kubectl get nodes
    NAME        STATUS     ROLES    AGE   VERSION
    k8s-node1   Ready      master   79m   v1.17.3
    k8s-node2   Ready      <none>   41m   v1.17.3
    k8s-node3   NotReady   <none>   41m   v1.17.3
    
    • 1
    • 2
    • 3
    • 4
    • 5

    得等个几分钟才能容灾恢复

    [root@k8s-node1 k8s]# kubectl get pods -o wide
    NAME                       READY   STATUS        RESTARTS   AGE     IP           NODE        NOMINATED NODE   READINESS GATES
    tomcat6-5f7ccf4cb9-clcpr   1/1     Running       0          4m16s   10.244.1.2   k8s-node2   <none>           <none>
    tomcat6-5f7ccf4cb9-xhrr9   1/1     Terminating   1          22m     10.244.2.2   k8s-node3   <none>           <none>
    
    • 1
    • 2
    • 3
    • 4
    2、暴露nginx访问

    在master上执行

    # tomcat镜像端口8080,转发到pod的80端口上,然后转发到虚拟机的XXX端口上(自动生成)
    kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort 
    
    • 1
    • 2

    pod的80映射容器的8080;server会带来pod的80

    查看服务:

    [root@k8s-node1 k8s]# kubectl get svc
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP        93m
    tomcat6      NodePort    10.96.7.78   <none>        80:30055/TCP   8s
    
    [root@k8s-node1 k8s]# kubectl get svc -o wide
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE     SELECTOR
    kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP        103m    <none>
    tomcat6      NodePort    10.96.7.78   <none>        80:30055/TCP   9m38s   app=tomcat6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    浏览器输入:http://192.168.56.100:30055/ ,可以看到tomcat首页

    输入下面命令可以看到pod和封装pod 的service,pod是部署产生的,部署还有一个副本

    [root@k8s-node1 ~]# kubectl get all
    NAME                           READY   STATUS    RESTARTS   AGE
    pod/tomcat6-5f7ccf4cb9-clcpr   1/1     Running   0          4h12m
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP        5h37m
    service/tomcat6      NodePort    10.96.7.78   <none>        80:30055/TCP   4h3m
    
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/tomcat6   1/1     1            1           4h30m
    
    NAME                                 DESIRED   CURRENT   READY   AGE
    replicaset.apps/tomcat6-5f7ccf4cb9   1         1         1       4h30m
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    3、动态扩容测试

    kubectl get deployment

    [root@k8s-node1 ~]# kubectl get deployment
    NAME      READY   UP-TO-DATE   AVAILABLE   AGE
    tomcat6   2/2     2            2           11h
    [root@k8s-node1 ~]# 
    
    • 1
    • 2
    • 3
    • 4

    应用升级: kubectl set image (–help查看帮助)

    扩容:kubectl scale --replicas=3 deployment tomcat6

    [root@k8s-node1 ~]# kubectl scale --replicas=3 deployment tomcat6
    deployment.apps/tomcat6 scaled
    [root@k8s-node1 ~]# kubectl get pods -o wide
    NAME                       READY   STATUS    RESTARTS   AGE     IP           NODE        NOMINATED NODE   READINESS GATES
    tomcat6-5f7ccf4cb9-clcpr   1/1     Running   0          4h23m   10.244.1.2   k8s-node2   <none>           <none>
    tomcat6-5f7ccf4cb9-jbvr4   1/1     Running   0          9s      10.244.2.3   k8s-node3   <none>           <none>
    tomcat6-5f7ccf4cb9-ng556   1/1     Running   0          9s      10.244.2.4   k8s-node3   <none>           <none>
    
    [root@k8s-node1 ~]# kubectl get svc -o wide
    NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE     SELECTOR
    kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP        5h48m   <none>
    tomcat6      NodePort    10.96.7.78   <none>        80:30055/TCP   4h15m   app=tomcat6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    扩容了多份,所有无论访问哪个node的指定端口,都可以访问到tomcat6

    http://192.168.56.101:30055/

    缩容:kubectl scale --replicas=2 deployment tomcat6

    [root@k8s-node1 ~]# kubectl scale --replicas=1 deployment tomcat6
    deployment.apps/tomcat6 scaled
    
    [root@k8s-node1 ~]# kubectl get pods -o wide
    NAME                       READY   STATUS    RESTARTS   AGE     IP           NODE        NOMINATED NODE   READINESS GATES
    tomcat6-5f7ccf4cb9-clcpr   1/1     Running   0          4h32m   10.244.1.2   k8s-node2   <none>           <none>
    
    [root@k8s-node1 ~]# kubectl get all
    NAME                           READY   STATUS    RESTARTS   AGE
    pod/tomcat6-5f7ccf4cb9-clcpr   1/1     Running   0          4h33m
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP        5h58m
    service/tomcat6      NodePort    10.96.7.78   <none>        80:30055/TCP   4h24m
    
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/tomcat6   1/1     1            1           4h51m
    
    NAME                                 DESIRED   CURRENT   READY   AGE
    replicaset.apps/tomcat6-5f7ccf4cb9   1         1         1       4h51m
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    4、以上操作的yaml获取

    # 尝试运行,并不会真正的创建镜像
    kubectl create deployment web --image=nginx -o yaml --dry-run
    
    • 1
    • 2

    5、删除

    kubectl delete deploye/nginx
    kubectl delete service/nginx-service
    
    • 1
    • 2

    kubectl get all

    [root@k8s-node1 ~]# kubectl get all
    NAME                           READY   STATUS    RESTARTS   AGE
    pod/tomcat6-5f7ccf4cb9-clcpr   1/1     Running   0          4h33m
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes   ClusterIP   10.96.0.1            443/TCP        5h58m
    service/tomcat6      NodePort    10.96.7.78           80:30055/TCP   4h24m
    
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/tomcat6   1/1     1            1           4h51m
    
    NAME                                 DESIRED   CURRENT   READY   AGE
    replicaset.apps/tomcat6-5f7ccf4cb9   1         1         1       4h51m
    #删除deployment.apps/tomcat6 
    [root@k8s-node1 ~]# kubectl delete deployment.apps/tomcat6
    deployment.apps "tomcat6" deleted
    #查看剩余的资源
    [root@k8s-node1 ~]# kubectl get all
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes   ClusterIP   10.96.0.1            443/TCP        6h
    service/tomcat6      NodePort    10.96.7.78           80:30055/TCP   4h26m
    # 此时没有了部署,但是有service,没有pod只有service也是没有对应的服务的
    
    # 查看pod信息
    [root@k8s-node1 ~]# kubectl get pods
    No resources found in default namespace.
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    三、docker深入

    docker笔记以后再发表吧,没整理好

    四、K8s细节

    这么这些内容我那个专栏里也有

    https://blog.csdn.net/hancoder/category_11140481.html

    https://kubernetes.io/zh/docs/reference/kubectl/overview/

    1、yaml输出

    https://kubernetes.io/zh/docs/reference/kubectl/overview/#资源类型

    在此示例中,以下命令将单个 pod 的详细信息输出为 YAML 格式的对象:

    kubectl get pod web-pod-13je7 -o yaml
    1
    
    • 1
    • 2

    请记住:有关每个命令支持哪种输出格式的详细信息,请参阅 kubectl 参考文档。

    –dry-run:

    –dry-run=‘none’: Must be “none”, “server”, or “client”. If client strategy, only print the object that would be

    sent, without sending it. If server strategy, submit server-side request without persisting the resource.

    值必须为,或。

    • none
    • server:提交服务器端请求而不持久化资源。
    • client:只打印该发送对象,但不发送它。

    也就是说,通过–dry-run选项,并不会真正的执行这条命令。

    # 输出yaml
    [root@k8s-node1 ~]# kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 --dry-run -o yaml
    
    W0504 03:39:08.389369    8107 helpers.go:535] --dry-run is deprecated and can be replaced with --dry-run=client.
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      creationTimestamp: null
      labels:
        app: tomcat6
      name: tomcat6
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: tomcat6
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: tomcat6
        spec:
          containers:
          - image: tomcat:6.0.53-jre8
            name: tomcat
            resources: {}
    status: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    实际上我们也可以将这个yaml输出到文件,然后使用kubectl apply -f来应用它

    #输出到tomcat6.yaml 
    [root@k8s-node1 ~]# kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 --dry-run -o yaml >tomcat6.yaml
    W0504 03:46:18.180366   11151 helpers.go:535] --dry-run is deprecated and can be replaced with --dry-run=client.
    
    • 1
    • 2
    • 3

    tomcat6.yaml 内容,修改一下副本个数为3

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      creationTimestamp: null
      labels:
        app: tomcat6
      name: tomcat6
    spec:
      replicas: 3 # 修改
      selector:
        matchLabels:
          app: tomcat6
      strategy: {}
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: tomcat6
        spec:
          containers:
          - image: tomcat:6.0.53-jre8
            name: tomcat
            resources: {}
    status: {}
    
    #应用tomcat6.yaml 
    [root@k8s-node1 k8s]# kubectl apply -f tomcat6.yaml
    deployment.apps/tomcat6 created
    [root@k8s-node1 k8s]# kubectl get pods
    NAME                       READY   STATUS    RESTARTS   AGE
    tomcat6-5f7ccf4cb9-hxqfl   1/1     Running   0          7s
    tomcat6-5f7ccf4cb9-ksm4n   1/1     Running   0          7s
    tomcat6-5f7ccf4cb9-qlzd4   1/1     Running   0          7s
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    查看某个pod的具体信息:

    [root@k8s-node1 ~]# kubectl get pods tomcat6-7b84fb5fdc-5jh6t  -o yaml
    
    • 1

    2、service

    可以去看 https://blog.csdn.net/hancoder/article/details/118070247

    Kubernetes Service定义了这样一种抽象:一个Pod的逻辑分组,一种可以访问它们的策略 —— 通常称为微服务。这一组Pod能够被Service访问到,通常是通过Label Selector

    通俗的讲:SVC负责检测Pod的状态信息,不会因pod的改动IP地址改变(因为关注的是标签),导致Nginx负载均衡影响

    在这里插入图片描述

    Service能够提供负载均衡的能力,但是在使用上有以下限制:

    • 默认只提供 4 层负载均衡能力(IP+端口),而没有 7 层功能(主机名和域名),但有时我们可能需要更多的匹配规则来转发请求,这点上 4 层负载均衡是不支持的
    • 后续可以通过Ingress方案,添加7层的能力
    # 1、部署一个nginx
    kubectl create deployment nginx --image=nginx
    
    # 2、暴露nginx访问
    kubectl expose deployment nginx --port=80 --type=NodePort
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    现在我们使用NodePort的方式暴露,这样访问每个节点的端口,都可以访问各个Pod,如果节点宕机,就会出现问题。

    前面我们通过命令行的方式,部署和暴露了tomcat,实际上也可以通过yaml的方式来完成这些操作。

    #这些操作实际上是为了获取Deployment的yaml模板
    [root@k8s-node1 ~]#  kubectl create deployment tomcat6 --image=tomcat:6.0.53-jre8 --dry-run -o yaml >tomcat6-deployment.yaml
    W0504 04:13:28.265432   24263 helpers.go:535] --dry-run is deprecated and can be replaced with --dry-run=client.
    [root@k8s-node1 ~]# ls tomcat6-deployment.yaml
    tomcat6-deployment.yaml
    [root@k8s-node1 ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改“tomcat6-deployment.yaml”内容如下:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        app: tomcat6
      name: tomcat6
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: tomcat6
      template:
        metadata: 
          labels:
            app: tomcat6
        spec:
          containers:
          - image: tomcat:6.0.53-jre8
            name: tomcat
    #部署
    [root@k8s-node1 ~]# kubectl apply -f tomcat6-deployment.yaml
    deployment.apps/tomcat6 configured
    
    
    #查看资源
    [root@k8s-node1 ~]# kubectl get all
    NAME                           READY   STATUS    RESTARTS   AGE
    pod/tomcat6-7b84fb5fdc-5jh6t   1/1     Running   0          27m
    pod/tomcat6-7b84fb5fdc-8lhwv   1/1     Running   0          27m
    pod/tomcat6-7b84fb5fdc-j4qmh   1/1     Running   0          27m
    
    NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
    service/kubernetes   ClusterIP   10.96.0.1    >        443/TCP   14h
    
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/tomcat6   3/3     3            3           27m
    
    NAME                                 DESIRED   CURRENT   READY   AGE
    replicaset.apps/tomcat6-7b84fb5fdc   3         3         3       27m
    [root@k8s-node1 ~]#
    kubectl expose deployment tomcat6 --port=80 --target-port=8080 --type=NodePort  --dry-run -o yaml
    1
    apiVersion: v1
    kind: Service # service
    metadata:
      creationTimestamp: null
      labels:
        app: tomcat6
      name: tomcat6
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: tomcat6 # 标签
      type: NodePort
    status:
      loadBalancer: {}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    关联部署和service

    将这段输出和“tomcat6-deployment.yaml”用---进行拼接,表示部署完毕并进行暴露服务:

    apiVersion: apps/v1
    kind: Deployment # 部署
    metadata:
      labels:
        app: tomcat6 # 标签
      name: tomcat6
    spec:
      replicas: 3 #副本数
      selector:
        matchLabels:
          app: tomcat6
      template:
        metadata: 
          labels:
            app: tomcat6
        spec:
          containers:
          - image: tomcat:6.0.53-jre8
            name: tomcat
    ---
    apiVersion: v1
    kind: Service
    metadata:
      creationTimestamp: null
      labels:
        app: tomcat6 # 标签
      name: tomcat6
    spec:
      ports:
      - port: 80
        protocol: TCP
        targetPort: 8080
      selector:
        app: tomcat6 # 标签
      type: NodePort
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 上面类型一个是Deployment,一个是Service

    部署并暴露服务

    [root@k8s-node1 ~]# kubectl apply -f tomcat6-deployment.yaml
    deployment.apps/tomcat6 created
    service/tomcat6 created
    
    • 1
    • 2
    • 3

    查看服务和部署信息

    [root@k8s-node1 ~]# kubectl get all
    NAME                           READY   STATUS    RESTARTS   AGE
    pod/tomcat6-7b84fb5fdc-dsqmb   1/1     Running   0          4s
    pod/tomcat6-7b84fb5fdc-gbmxc   1/1     Running   0          5s
    pod/tomcat6-7b84fb5fdc-kjlc6   1/1     Running   0          4s
    
    NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
    service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP        14h
    service/tomcat6      NodePort    10.96.147.210   <none>        80:30172/TCP   4s
    
    NAME                      READY   UP-TO-DATE   AVAILABLE   AGE
    deployment.apps/tomcat6   3/3     3            3           5s
    
    NAME                                 DESIRED   CURRENT   READY   AGE
    replicaset.apps/tomcat6-7b84fb5fdc   3         3         3       5s
    [root@k8s-node1 ~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    访问node1,node1和node3的30172端口:

    [root@k8s-node1 ~]# curl -I http://192.168.56.{100,101,102}:30172/
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    Accept-Ranges: bytes
    ETag: W/"7454-1491118183000"
    Last-Modified: Sun, 02 Apr 2017 07:29:43 GMT
    Content-Type: text/html
    Content-Length: 7454
    Date: Mon, 04 May 2020 04:35:35 GMT
    
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    Accept-Ranges: bytes
    ETag: W/"7454-1491118183000"
    Last-Modified: Sun, 02 Apr 2017 07:29:43 GMT
    Content-Type: text/html
    Content-Length: 7454
    Date: Mon, 04 May 2020 04:35:35 GMT
    
    HTTP/1.1 200 OK
    Server: Apache-Coyote/1.1
    Accept-Ranges: bytes
    ETag: W/"7454-1491118183000"
    Last-Modified: Sun, 02 Apr 2017 07:29:43 GMT
    Content-Type: text/html
    Content-Length: 7454
    Date: Mon, 04 May 2020 04:35:35 GMT
    
    [root@k8s-node1 ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    现在的问题是service的3个pod都可以访问,但怎么创建个总的管理者,以便负载均衡

    3、Ingress

    通过Ingress发现pod进行关联。基于域名访问
    通过Ingress controller实现POD负载均衡
    支持TCP/UDP 4层负载均衡和HTTP 7层负载均衡

    可以把ingress理解为nginx,通过域名访问service端口

    • Ingress管理多个service
    • service管理多个pod

    步骤:
    (1)部署Ingress controller

    执行“k8s/ingress-controller.yaml”,

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
    	name: web
    spec:
    	rules:
    	- host:tomcat6.atguigu.com
    	  http:
    	  	paths:
    	  		-backend:
    	  			serviceName: tomcat6
    	  			servicePort: 80
    123456789101112
    [root@k8s-node1 k8s]# kubectl apply -f ingress-controller.yaml 
    namespace/ingress-nginx created
    configmap/nginx-configuration created
    configmap/tcp-services created
    configmap/udp-services created
    serviceaccount/nginx-ingress-serviceaccount created
    clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
    role.rbac.authorization.k8s.io/nginx-ingress-role created
    rolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
    clusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding created
    daemonset.apps/nginx-ingress-controller created
    service/ingress-nginx created
    [root@k8s-node1 k8s]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    查看

    [root@k8s-node1 k8s]# kubectl get pods --all-namespaces
    NAMESPACE       NAME                                READY   STATUS              RESTARTS   AGE
    default         tomcat6-7b84fb5fdc-dsqmb            1/1     Running             0          16m
    default         tomcat6-7b84fb5fdc-gbmxc            1/1     Running             0          16m
    default         tomcat6-7b84fb5fdc-kjlc6            1/1     Running             0          16m
    ingress-nginx   nginx-ingress-controller-9q6cs      0/1     ContainerCreating   0          40s
    ingress-nginx   nginx-ingress-controller-qx572      0/1     ContainerCreating   0          40s
    kube-system     coredns-546565776c-9sbmk            1/1     Running             1          14h
    kube-system     coredns-546565776c-t68mr            1/1     Running             1          14h
    kube-system     etcd-k8s-node1                      1/1     Running             1          14h
    kube-system     kube-apiserver-k8s-node1            1/1     Running             1          14h
    kube-system     kube-controller-manager-k8s-node1   1/1     Running             1          14h
    kube-system     kube-flannel-ds-amd64-5xs5j         1/1     Running             2          13h
    kube-system     kube-flannel-ds-amd64-6xwth         1/1     Running             2          14h
    kube-system     kube-flannel-ds-amd64-fvnvx         1/1     Running             1          13h
    kube-system     kube-proxy-7tkvl                    1/1     Running             1          13h
    kube-system     kube-proxy-mvlnk                    1/1     Running             2          13h
    kube-system     kube-proxy-sz2vz                    1/1     Running             1          14h
    kube-system     kube-scheduler-k8s-node1            1/1     Running             1          14h
    [root@k8s-node1 k8s]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    这里master节点负责调度,具体执行交给node2和node3来完成,能够看到它们正在下载镜像

    image-20200504124608258

    (2)创建Ingress规则

    ingress-tomcat6.yaml

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: web
    spec:
      rules:
      - host: tomcat6.kubenetes.com
        http:
           paths: 
              - backend: 
                  serviceName: tomcat6
                  servicePort: 80
    123456789101112
    [root@k8s-node1 k8s]# touch ingress-tomcat6.yaml
    #将上面的规则,添加到ingress-tomcat6.yaml文件中
    [root@k8s-node1 k8s]# vi  ingress-tomcat6.yaml  
     
    [root@k8s-node1 k8s]# kubectl apply -f ingress-tomcat6.yaml 
    ingress.extensions/web created
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    修改本机的hosts文件,添加如下的域名转换规则:

    192.168.56.102 tomcat6.kubenetes.com
    
    • 1

    测试: http://tomcat6.kubenetes.com/ 访问到tomcat

    并且集群中即便有一个节点不可用,也不影响整体的运行。

    10、安装kubernetes可视化界面——DashBoard

    同样网上可以找到yaml:https://gitee.com/CaiJinHao/kubernetesdashboard/tree/v1.10.1/src/deploy/recommended

    1、部署DashBoard

    $ kubectl apply -f  kubernetes-dashboard.yaml
    
    • 1

    2、暴露DashBoard为公共访问

    默认DashBoard只能集群内部访问,修改Service为NodePort类型,暴露到外部

    kind: Service
    apiVersion: v1
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
      name: kubernetes-dashboard
      namespace: kube-system
    spec:
      type: NodePort
      ports:
        - port: 443
          targetPort: 8443
          nodePort: 3001
      selector:
        k8s-app: kubernetes-dashboard
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    3、创建授权账号

    $ kubectl create serviceaccount dashboar-admin -n kube-sysem
    
    $ kubectl create clusterrolebinding dashboar-admin --clusterrole=cluter-admin --serviceaccount=kube-system:dashboard-admin
    
    $ kubectl describe secrets -n kube-system $( kubectl -n kube-system get secret |awk '/dashboard-admin/{print $1}' )
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用输出的token登录dashboard

    image-20200504153630775

    二、kubesphere

    这个章节不怎么写了,请参考我的另外一篇博客 https://blog.csdn.net/hancoder/article/details/118053239 在文末

    默认的dashboard没啥用,kubesphere可以打通全部的devops链路,kubesphere集成了很多套件,集群要求比较高

    DevOps

    Mysql集群

    数据库的可以去我的专栏阅读:https://blog.csdn.net/hancoder/category_9488515.html

    Mysql-MMM简介

    MMM(Master-Master replication manager for MySQL)是一套支持双主故障切换和双主日常管理的脚本程序。MMM使用Perl语言开发,主要用来监控和管理MySQL Master-Master(双主)复制,虽然叫做双主复制,但是业务上同一时刻只允许对一个主进行写入,另一台备选主上提供部分读服务,以加速在主主切换时刻备选主的预热,可以说MMM这套脚本程序一方面实现了故障切换的功能,另一方面其内部附加的工具脚本也可以实现多个slave的read负载均衡。

    MMM提供了自动和手动两种方式移除一组服务器中复制延迟较高的服务器的虚拟ip,同时它还可以备份数据,实现两节点之间的数据同步等。由于MMM无法完全的保证数据一致性,所以MMM适用于对数据的一致性要求不是很高,但是又想最大程度的保证业务可用性的场景。对于那些对数据的一致性要求很高的业务,非常不建议采用MMM这种高可用架构。

    正常工作是一主2从,master1主挂掉之后,monitor会把写IP交给master2,而客户端实际还是用的原来的IP,这个工作就是monitor做的

    但是也有数据一致性问题,只是解决了IP偏移问题

    优点:

    1 稳定和成熟的开源产品,经过了时间的考验 核心技术是mysql自己的技术,只是使用脚本程序来控制,所以在原理上比较容易理解,而且管理能够更智能化。
    2 安装简单,配置简单,使用简单
    3 功能强大 (HA,failover,tools套件,cluster模式可以一个monitor管理多个mmm组)
    123
    
    • 1
    • 2
    • 3
    • 4

    缺点:

    1 由于架构里只有一个写入点,所以扩展性是有限的,但是对一般中型企业够用了。
       解决方案:对于大应用可以采取垂直拆分到多个mmm架构的方式,使用mmm cluster来管理。 
    2 对于读写分离和读负载均衡还是要程序来开发或者使用其他工具完成。
    
    • 1
    • 2
    • 3

    MHA

    MHA(Master High Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,它由日本 DeNA 公司的 youshimaton(现就职于 Facebook 公司)开发,是一套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。

    在 MySQL 故障切换过程中,MHA 能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

    该软件由两部分组成:MHA Manager(管理节点)和 MHA Node(数据节点)。MHA Manager 可以单独部署在一台独立的机器上管理多个 master-slave 集群,也可以部署在一台 slave 节点上。MHA Node 运行在每台 MySQL 服务器上,MHA Manager 会定时探测集群中的 master 节点,当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master,然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。

    在 MHA 自动故障切换过程中,MHA 试图从宕机的主服务器上保存二进制日志,最大程度的保证数据的不丢失,但这并不总是可行的。例如,如果主服务器硬件故障或无法通过ssh访问,MHA 没法保存二进制日志,只进行故障转移而丢失了最新的数据。使用 MySQL 5.5 的半同步复制,可以大大降低数据丢失的风险。MHA 可以与半同步复制结合起来。如果只有一个 slave 已经收到了最新的二进制日志,MHA 可以将最新的二进制日志应用于其他所有的 slave 服务器上,因此可以保证所有节点的数据一致性。

    目前 MHA 主要支持一主多从的架构,要搭建 MHA,要求一个复制集群中必须最少有三台数据库服务器,一主二从,即一台充当 master,一台充当备用 master,另外一台充当从库,因为至少需要三台服务器,出于机器成本的考虑,淘宝也在该基础上进行了改造,目前淘宝TMHA已经支持一主一从。

    InnoDB Cluster

    参考:https://blog.csdn.net/wzy0623/article/details/100779450

    最初的MySQL版本只提供一种简单的主从异步复制,满足最基本的数据同步。为了提高复制性能,从单线程到组提交再到多线程复制,基本解决了复制延迟问题。

    • 为了解决从库与主库的一致性读问题,新增了半同步复制
    • 为了提供自动故障转移功能,又提供了组复制功能。
    • 要做到真正的高可用,失败切换必须对应用透明,于是在组复制的基础上,又发展出了InnoDB Cluster。

    InnoDB Cluster出现前,实现MySQL数据库的的高可用性,除了原生的复制功能,通常还需要借助第三方中间件,如Keepalived、MHA等等。

    整体结构

    InnoDB Cluster主要由MySQL ShellMySQL RouterMySQL服务器集群组成,三者协同工作,共同为MySQL提供完整的高可用性解决方案。图1所示为InnoDB Cluster的整体架构。

    img

    InnoDB Cluster以组复制为基础,集群中的每个MySQL服务器实例都是组复制的成员,提供了在InnoDB Cluster内复制数据的机制,并且具有内置的故障转移功能。

    • MySQL Shell在InnoDB Cluster中充当控制台角色,使用它包含的AdminAPI,可以使安装、配置、管理、维护多个MySQL组复制实例的工作更加轻松。通过AdminAPI的几条交互指令就可自动完成组复制配置。
    • MySQL Router可以根据集群部署信息自动生成配置,将客户端应用程序透明地连接到MySQL服务器实例。如果服务器实例意外故障,群集将自动重新配置。在默认的单主模式下,InnoDB Cluster 具有单个读写主服务器实例。多个辅助服务器实例是主服务器实例的副本。如果主服务器出现故障,则辅助服务器将自动升级为主服务器。MySQL Router可以检测到这种情况并将客户端应用程序自动转发到新的主服务器。

    用户连MySQL Router,MySQL Router去调度读写

    企业级方案

    这里写图片描述

    这里写图片描述

    在中小型互联网的企业中。mysql的集群一般就是上图的架构。WEB节点读取数据库的时候读取dbproxy服务器。dbproxy服务器通过对SQL语句的判断来进行数据库的读写分离。读请求负载到从库(也可以把主库加上),写请求写主库。

    这里的dbproxy是数据库集群的唯一出口所以也需要做高可用。

    drproxy是数据库读写分离的常用软件,amoeba、mycat、cobar也很常用。这类软件不仅带有读写分离功能,还可以实现负载均衡以及后端节点的健康检查。

    数据库的读写分离除了通过这类数据库中间件软件实现,还可以写在程序中。

    通常我们的主库要做双主高可用,实现主库挂掉另一个主库立刻接管。如果不做双主,从库接管主库的时候需要做状态迁移,会有延迟。

    数据库主库的高可用重点需要考虑的是数据同步。比较常用的高可用方案有:

    • 1、keepalived+mysql replication。通过keepalived实现VIP飘逸,通过mysql自带的同步方案replication实现数据同步。
    • 2、hearbeat+drbd。通过drbd实现双主数据的同步,这个数据同步是基于块设备的。比一般的同步方案要快很多。通过heartbeat实现VIP漂移以及drbd资源的切换管理。
    • 3、keepalived+mha。

    对于从库,最好不要超过5个。我们可以把其中的三个作为用户访问的节点,把另外一个作为内部人员的查询节点。因为内部人员查询节点的时候一般是按照时间段查询,不经过索引,占用的资源比较多,所以要把这个节点单独专用,以免影响客户访问。最后我们应该留一个从库进行数据库的数据备份。

    从库的数据一致性保持可以通过直接于主库进行主从辅助,也可以从其他从库那进行主从复制(优点是减少主库压力,缺点是延迟稍大)、

    2、MYSQL数据架构

    数据库服务器==》数据库(多个实例)》多个库》多个表==》多个字段行列(数据)

    在一台数据库服务器上可以跑多个实例,一个实例中有多个库,一个库有多个表,一个表有多个行列。

    这里写图片描述

    搭建主从复制集群

    P362

    • MASTER:创建docker,映射到3307,-v挂载文件夹到主机
    • slave:3317
    sudo docker run -p 3307:3306 --name mysql-master \
    -v /mydata/mysql/master/log:/var/log/mysql \
    -v /mydata/mysql/master/data:/var/lib/mysql \
    -v /mydata/mysql/master/conf:/etc/mysql \
    -e MYSQL_ROOT_PASSWORD=root \
    -d mysql:5.7
    sudo docker run -p 3317:3306 --name mysql-slave1 \
    -v /mydata/mysql/slaver/log:/var/log/mysql \
    -v /mydata/mysql/slaver/data:/var/lib/mysql \
    -v /mydata/mysql/slaver/conf:/etc/mysql \
    -e MYSQL_ROOT_PASSWORD=root \
    -d mysql:5.7
    vim /mydata/mysql/master/conf/my.cnf
    
    [client]
    default-character-set=utf8
    [mysql]
    default-character-set=utf8
    [mysqld]
    init_connect='SET collation_connection = utf8_unicode_ci'
    init_connect='SET NAMES utf8'
    character-set-server=utf8
    collation-server=utf8_unicode_ci
    skip-character-set-client-handshake
    skip-name-resolve
    # skip-name-resolve一定要加,否则会很慢
    vim /mydata/mysql/slaver/conf/my.cnf
    
    [client]
    default-character-set=utf8
    [mysql]
    default-character-set=utf8
    [mysqld]
    init_connect='SET collation_connection = utf8_unicode_ci'
    init_connect='SET NAMES utf8'
    character-set-server=utf8
    collation-server=utf8_unicode_ci
    skip-character-set-client-handshake
    skip-name-resolve
    # skip-name-resolve一定要加,否则会很慢
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    然后添加机器信息了

    有机会我会把binlog相关的博客发出来

    vim /mydata/mysql/master/conf/my.cnf
    
    server_id=1
    log-bin=mysql-bin
    read-only=0
    binlog-do-db=gulimall_ums
    binlog-do-db=gulimall_pms
    binlog-do-db=gulimall_oms
    binlog-do-db=gulimall_sms
    binlog-do-db=gulimall_wms
    binlog-do-db=gulimall_admin
    
    # 不主从复制的数据库
    replicate-ignore-db=mysql
    replicate-ignore-db=sys
    replicate-ignore-db=information_schema
    replicate-ignore-db=performance_schema
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    开始配置slave

    vim /mydata/mysql/slaver/conf/my.cnf
    
    server_id=2
    log-bin=mysql-bin
    read-only=1
    binlog-do-db=gulimall_ums
    binlog-do-db=gulimall_pms
    binlog-do-db=gulimall_oms
    binlog-do-db=gulimall_sms
    binlog-do-db=gulimall_wms
    binlog-do-db=gulimall_admin
    
    # 不主从复制的数据库
    replicate-ignore-db=mysql
    replicate-ignore-db=sys
    replicate-ignore-db=information_schema
    replicate-ignore-db=performance_schema
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    重启、开发master的权限、

    #  重启master容器,
    docker restart mysql-master mysql-slaver1
    
    # 进入master容器内部
    docker exec -it mysql /bin/bash
    grant all privileges on *.* to 'root'@'%' identified by '123456'
    flush privileges;
    
    # 在mysql命令行中
    GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by '123456'
    
    SHOW MASTER STATUS;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在从库中

    # 设置主从链接
    change master to
    master_host='192.168.56.10',master_user='backup',master_password='123456',master_log_file='mysql-bn.000001',master_log_pos=0,master_port=3307l
    
    # master上执行
    start slave;
    show slave status;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    ShardingSphere

    解决master分片存储,分库分表

    比如在配置文件里配置

    # 第一个服务器
    auto_increment_offset:1 # 初始
    auto_increment_increment:2 # 步长
    
    # 第2个服务器
    auto_increment_offset:2 # 初始
    auto_increment_increment:2 # 步长
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    但是不好维护,不使用这种

    https://shardingsphere.apache.org/index_zh.html

    Apache ShardingSphere 是一套开源的分布式数据库解决方案组成的生态圈,它由 JDBC、Proxy 和 Sidecar(规划中)这 3 款既能够独立部署,又支持混合部署配合使用的产品组成。 它们均提供标准化的数据水平扩展、分布式事务和分布式治理等功能,可适用于如 Java 同构、异构语言、云原生等各种多样化的应用场景。

    ShardingSphere-Proxy Architecture

    下载ShardingSphere-Proxy

    https://shardingsphere.apache.org/document/current/cn/user-manual/shardingsphere-proxy/

    数据源配置:https://shardingsphere.apache.org/document/4.1.0/cn/manual/sharding-proxy/configuration/

    Sharding-Proxy支持多逻辑数据源,每个以config-前缀命名的yaml配置文件,即为一个逻辑数据源。以下是config-xxx.yaml的配置配置示例。

    schemaName: # 逻辑数据源名称
    
    dataSources: # 数据源配置,可配置多个 
      : # 与 ShardingSphere-JDBC 配置不同,无需配置数据库连接池
        url: #数据库 URL 连接
        username: # 数据库用户名
        password: # 数据库密码
        connectionTimeoutMilliseconds: # 连接超时毫秒数
        idleTimeoutMilliseconds: # 空闲连接回收超时毫秒数
        maxLifetimeMilliseconds: # 连接最大存活时间毫秒数
        maxPoolSize: 50 # 最大连接数
        minPoolSize: 1  # 最小连接数     
    
    rules: # 与 ShardingSphere-JDBC 配置一致
      # ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    下载mysql驱动放到ShardingSphere-Proxy /lib中

    server.yaml

    config-readwrite-splitting.yaml

    config-sharding.yaml

    schemaName: sharding_db
    #
    dataSources:
      ds_0:
    #    url: jdbc:postgresql://127.0.0.1:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
    #    username: postgres
    #    password: postgres
    #    connectionTimeoutMilliseconds: 30000
    #    idleTimeoutMilliseconds: 60000
    #    maxLifetimeMilliseconds: 1800000
    #    maxPoolSize: 50
    #    minPoolSize: 1
    #    maintenanceIntervalMilliseconds: 30000
      ds_1:
    #    url: jdbc:postgresql://127.0.0.1:3317/demo_ds_1?serverTimezone=UTC&useSSL=false
    #    username: postgres
    #    password: postgres
    #    connectionTimeoutMilliseconds: 30000
    #    idleTimeoutMilliseconds: 60000
    #    maxLifetimeMilliseconds: 1800000
    #    maxPoolSize: 50
    #    minPoolSize: 1
    #    maintenanceIntervalMilliseconds: 30000
    ######################################################################################################
    
    
    #rules:
    #- !SHARDING
    #  tables:
    #    t_order:
    #      actualDataNodes: ds_${0..1}.t_order_${0..1}
    #      tableStrategy:
    #        standard:
              shardingColumn: order_id  # 根据这个字段分表
              shardingAlgorithmName: t_order_inline
          keyGenerateStrategy: # 主键生成策略  #雪花算法
            column: order_id
            keyGeneratorName: snowflake
        t_order_item:
    #      actualDataNodes: ds_${0..1}.t_order_item_${0..1}
    #      tableStrategy:
    #        standard:
              shardingColumn: order_id # 这样这2个表就在一个库中了
              shardingAlgorithmName: t_order_item_inline
    #      keyGenerateStrategy:
    #        column: order_item_id
    #        keyGeneratorName: snowflake
      bindingTables:
        - t_order,t_order_item
        
      defaultDatabaseStrategy: # 分库
        standard: 
          shardingColumn: user_id # 根据用户id分库
          shardingAlgorithmName: database_inline
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    config-master_slave.yaml

    dataSources:
     # 2主2从
     master_0_ds:
       url: jdbc:postgresql://192.168.56.10:3307/demo_ds_0?serverTimezone=UTC&useSSL=false
       username: root
       password: root
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
     slave_ds_0:
       url: jdbc:postgresql://192.168.56.10:3317/demo_ds_0?serverTimezone=UTC&useSSL=false
       username: root
       password: root
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
     master_1_ds:
       url: jdbc:postgresql://192.168.56.10:3307/demo_ds_1?serverTimezone=UTC&useSSL=false
       username: root
       password: root
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
     slave_ds_1:
       url: jdbc:postgresql://192.168.56.10:3317/demo_ds_1?serverTimezone=UTC&useSSL=false
       username: root
       password: root
       connectionTimeoutMilliseconds: 30000
       idleTimeoutMilliseconds: 60000
       maxLifetimeMilliseconds: 1800000
       maxPoolSize: 50
    # 2套主从规则
    masterSlaveRule:
     name: ms_ds1
     masterDataSourceName: master_0_ds
     slaveDataSourceNames:
       - slave_ds_0
     # 另放到一个文件在
     # name: ms_ds2:
     # masterDataSourceName: master_1_ds
     # slaveDataSourceNames:
       # - slave_ds_1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    去docker里先停掉,然后添加上主从复制的库

    然后链接上sharding-proxy,insert的时候无需指定主键,雪花算法就生成主键了

    在sharding里看到的是全部数据,在物理库中是分开的

    Redis集群

    • 传统:jedis判断要去哪个redis、代表有redis sharding。缺点是redis宕机后客户端感知不到没法容灾
    • 代理:和前面讲的意义,客户端连接虚拟代理。代表有Twemproxy、Codis
    • redis-cluster:(官方、推荐)

    之前是利用哨兵来主从切换。

    1)槽点

    cluster是多主多从,用了16384个哈希槽,可以根据性能将不同的槽位分配给redis实例

    CRC16(key)%16383
    1
    
    • 1
    • 2

    缺点:

    • 客户端会随便连个redis,然后redis告诉客户端去哪个redis里找,客户端重新请求一遍
    • mset、mget等操作,多个key批量时只支持slot值相同的批量操作。
    • 事务支持有限。但是我们一般使用lua脚本

    2)一致性哈希

    不讲了,很多地方有讲。

    重分布时只重分别一个区间内的。

    可以使用虚拟结点解决数据倾斜的问题。

    搭建:简单阅读下下面的步骤,docker原理也差不多

    1、准备6台redis,都配置上 masterauth (不清楚的可参考我的另一篇博客《Redis主从、哨兵》)

    2、修改核心配置 vim /usr/local/redis/redis.conf

    # 开启集群模式
    cluster-enabled yes
    # 每一个节点需要有一个配置文件,需要6份。每个节点处于集群的角色都需要告知其他所有节点,彼此知道,这个文件用于存储集群模式下的集群状态等信息,这个文件是由redis自己维护,我们不用管。如果你要重新创建集群,那么把这个文件删了就行
    cluster-config-file nodes-201.conf
    # 超时时间,超时则认为master宕机,随后主备切换
    cluster-node-timeout 5000
    # 开启AOF
    appendonly yes
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3、删除工作空间中rdb和aof文件

    4、分别启动6台redis

    5、创建集群,在任一节点上执行以下命令,执行完会出现日志,6台的主从关系都会显示。

    #####
    # 注意1:如果你使用的是redis3.x版本,需要使用redis-trib.rb来构建集群,最新版使用C语言来构建了,这个要注意
    # 注意2:以下为新版的redis构建方式
    #####
    
    # 创建集群,主节点和从节点比例为1,主从的对应关系会自动分配。
    redis-cli --cluster create ip1:port1 ip2:port2 ip3:port3 ip4:port4 ip5:port5 ip6:port6 --cluster-replicas 1
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    6、检查

    redis-cli -a imooc --cluster check 192.168.25.64:6380
    
    • 1

    7、可自行测试其中一台或几台挂掉是否依然可用。

    至此,在保证了高可用的同时,也扩展了容量。

    ES集群

    ES笔记可以读下:

    • https://blog.csdn.net/hancoder/article/details/113922398
    • 正规笔记没有发表到博客上,有时间整理好再发吧

    MASTER结点不存储数据

    每一个索引都分片,分片还能有副本

    在单机下集群配置只要cluster.name一致就会加入到集群。但是在不同主机上,需要配置一个可链接到的单播主机列表。

    笔记不易:

    离线笔记均为markdown格式,图片也是云图,10多篇笔记20W字,压缩包仅500k,推荐使用typora阅读。也可以自己导入有道云笔记等软件中

    阿里云图床现在每周得几十元充值,都要自己往里搭了,麻烦不要散播与转发

    img

    打赏后请主动发支付信息到邮箱 553736044@qq.com ,上班期间很容易忽略收账信息,邮箱回邮基本秒回

    禁止转载发布,禁止散播,若发现大量散播,将对本系统文章图床进行重置处理。

    技术人就该干点技术人该干的事

    如果帮到了你,留下赞吧,谢谢支持

  • 相关阅读:
    Hadoop运行模式(五)、编写Hadoop集群常用脚本、Hadoop集群启停脚本、常用端口号说明、集群时间同步、时间服务器配置、其他机器配置
    基于ghOSt用户调度器的环境搭建
    MySQL——自增长
    【无标题】std::thread
    统计学习第一章
    详解 Intersection Observer API ( 交叉观察器 )
    软件设计模式白话文系列(十三)模版方法模式
    springboot+redis水果超市商城系统(源码+sql+论文报告)
    Java技术分享系列:Dubbo 与 Spring Cloud 完美结合
    Linux 使用ss命令停止指定端口进程
  • 原文地址:https://blog.csdn.net/qq_44125678/article/details/128067999