k8s一键部署搭建大数据集群_一键部署k8s高可用集群脚本 - CSDN
精华内容
参与话题
  • 本文将从零开始,在干净的机器上...开始部署之前,请先确定当前满足如下条件,本次集群搭建,所有机器处于同一内网网段,并且可以互相通信。 ⚠️⚠️⚠️:请详细阅读第一部分,后面的所有操作都是基于这个环境的.

    本文将从零开始,在干净的机器上安装 Docker、Kubernetes (使用 kubeadm)、Calico、Helm、NFS StorageClass,通过手把手的教程演示如何搭建一个高可用生产级的 Kubernetes,并在 Kubernetes 集群之上安装开源的 KubeSphere 容器平台可视化运营集群环境。

    k8s1.16.3+Traefik 2.0.5另一篇解决端口暴露HTTP https问题,没有用ingress-controll

    https://blog.csdn.net/u014756339/article/details/108173417

    一、准备环境

    开始部署之前,请先确定当前满足如下条件,本次集群搭建,所有机器处于同一内网网段,并且可以互相通信。

    ⚠️⚠️⚠️:请详细阅读第一部分,后面的所有操作都是基于这个环境的,为了避免后面部署集群出现各种各样的问题,强烈建议你完全满足第一部分的环境要求

    • 两台以上主机
    • 每台主机的主机名、Mac 地址、UUID 不相同
    • CentOS 7(本文用 7.6/7.7)
    • 每台机器最好有 2G 内存或以上
    • Control-plane/Master至少 2U 或以上
    • 各个主机之间网络相通
    • 禁用交换分区
    • 禁用 SELINUX
    • 关闭防火墙(你也可以设置相关防火墙规则)!!!阿里云等安全组开放相关端口
    • Control-plane/Master和Worker节点分别开放如下端口

    Master节点

    协议 方向 端口范围 作用 使用者
    TCP 入站 6443* Kubernetes API 服务器 所有组件
    TCP 入站 2379-2380 etcd server client API kube-apiserver, etcd
    TCP 入站 10250 Kubelet API kubelet 自身、控制平面组件
    TCP 入站 10251 kube-scheduler kube-scheduler 自身
    TCP 入站 10252 kube-controller-manager kube-controller-manager 自身

    Worker节点

    协议 方向 端口范围 作用 使用者
    TCP 入站 10250 Kubelet API kubelet 自身、控制平面组件
    TCP 入站 30000-32767 NodePort 服务** 所有组件

    其他相关操作如下:

    友情提示😊,如果集群过多,可以了解下 批量工具,批量管理你的多台机器,方便实用的工具。如ansible,傻瓜BatchShell 批量传输等

    先进行防火墙、交换分区设置

    # 为了方便本操作关闭了防火墙,也建议你这样操作
    systemctl stop firewalld
    systemctl disable firewalld
    
    # 关闭 SeLinux
    setenforce 0
    sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
    
    # 关闭 swap
    swapoff -a
    yes | cp /etc/fstab /etc/fstab_bak
    cat /etc/fstab_bak |grep -v swap > /etc/fstab

    更换CentOS YUM源为阿里云yum源

    # 安装wget
    yum install wget -y
    # 备份
    mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
    # 获取阿里云yum源
    wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
    # 获取阿里云epel源
    wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
    # 清理缓存并创建新的缓存
    yum clean all && yum makecache
    # 系统更新
    yum update -y

    进行时间同步,并确认时间同步成功

    timedatectl
    timedatectl set-ntp true

    ⚠️⚠️⚠️以下操作请严格按照声明的版本进行部署,否则将碰到乱七八糟的问题

    二、安装 Docker

    2.1、安装 Docker

    您需要在每台机器上安装 Docker,我这里安装的是 docker-ce-19.03.4

    # 安装 Docker CE
    # 设置仓库
    # 安装所需包
    yum install -y yum-utils \
        device-mapper-persistent-data \
        lvm2
    
    # 新增 Docker 仓库,速度慢的可以换阿里云的源。
    yum-config-manager \
        --add-repo \
        https://download.docker.com/linux/centos/docker-ce.repo
    # 阿里云源地址
    # http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
    # 安装 Docker CE.
    yum install -y containerd.io-1.2.10 \
        docker-ce-19.03.4 \
        docker-ce-cli-19.03.4
    
    # 启动 Docker 并添加开机启动
    systemctl start docker
    systemctl enable docker

    2.2、修改 Cgroup Driver

    需要将Docker 的 Cgroup Driver 修改为 systemd,不然在为Kubernetes 集群添加节点时会报如下错误:

    # 执行 kubeadm join 的 WARNING 信息
    [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/

    目前 Docker 的 Cgroup Driver 看起来应该是这样的:

    $ docker info|grep "Cgroup Driver"
      Cgroup Driver: cgroupfs

    需要将这个值修改为 systemd ,同时我将registry替换成国内的一些仓库地址,以免直接在官方仓库拉取镜像会很慢,操作如下。

    ⚠️⚠️⚠️:注意缩进,直接复制的缩进可能有问题,请确保缩进为正确的 Json 格式;如果 Docker 重启后查看状态不正常,大概率是此文件缩进有问题,Json格式的缩进自己了解一下。

    # Setup daemon.
    cat > /etc/docker/daemon.json <<EOF
    {
        "exec-opts": ["native.cgroupdriver=systemd"],
        "log-driver": "json-file",
        "log-opts": {
        "max-size": "100m"
        },
        "storage-driver": "overlay2",
        "registry-mirrors":[
            "https://kfwkfulq.mirror.aliyuncs.com",
            "https://2lqq34jg.mirror.aliyuncs.com",
            "https://pee6w651.mirror.aliyuncs.com",
            "http://hub-mirror.c.163.com",
            "https://docker.mirrors.ustc.edu.cn",
            "https://registry.docker-cn.com"
        ]
    }
    EOF
    
    mkdir -p /etc/systemd/system/docker.service.d
    
    # Restart docker.
    systemctl daemon-reload
    systemctl restart docker

    三、安装 kubeadm、kubelet 和 kubectl

    3.1、安装准备

    需要在每台机器上安装以下的软件包:

    • kubeadm:用来初始化集群的指令。
    • kubelet:在集群中的每个节点上用来启动 pod 和容器等。
    • kubectl:用来与集群通信的命令行工具(Worker 节点可以不装,但是我装了,不影响什么)。
    # 配置K8S的yum源
    # 这部分用是阿里云的源,如果可以访问Google,则建议用官方的源
    cat <<EOF > /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg       http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
    EOF
    
    # 官方源配置如下
    cat <<EOF > /etc/yum.repos.d/kubernetes.repo
    [kubernetes]
    name=Kubernetes
    baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
    enabled=1
    gpgcheck=1
    repo_gpgcheck=1
    gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
    EOF

    3.2、开始安装

    安装指定版本 kubelet、 kubeadm 、kubectl, 我这里选择当前较新的稳定版 Kubernetes 1.17.3,如果选择的版本不一样,在执行集群初始化的时候,注意 –kubernetes-version 的值。

    # 增加配置
    cat <<EOF > /etc/sysctl.d/k8s.conf
    net.ipv4.ip_forward=1
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    EOF
    # 加载
    sysctl --system
    
    # 安装
    yum install -y kubelet-1.17.3 kubeadm-1.17.3 kubectl-1.17.3 --disableexcludes=kubernetes
    
    # 启动并设置 kubelet 开机启动
    systemctl daemon-reload
    systemctl start kubelet
    systemctl enable --now kubelet

    ⚠️⚠️⚠️WARNING

    如果此时执行 systemctl status kubelet 命令,系统日志将得到 kubelet 启动失败的错误提示,请忽略此错误,因为必须完成后续步骤中 kubeadm init 的操作,kubelet 才能正常启动

    四、使用 Kubeadm 创建集群

    4.1、初始化 Control-plane/Master 节点

    在第一台 Master 上执行初始化,执行初始化使用 kubeadm init 命令。初始化首先会执行一系列的运行前检查来确保机器满足运行 Kubernetes 的条件,这些检查会抛出警告并在发现错误的时候终止整个初始化进程。 然后 kubeadm init 会下载并安装集群的 Control-plane 组件。

    在初始化之前,需要先设置一下 hosts 解析,为了避免可能出现的问题,后面的 Worker 节点我也进行了同样的操作。注意按照你的实际情况修改Master节点的IP,并且注意 APISERVER_NAME 的值,如果你将这个 apiserver 名称设置为别的值,下面初始化时候的 –control-plane-endpoint 的值保持一致。

    提示:为了使 Kubernetes 集群高可用,建议给集群的控制节点配置负载均衡器,如 HAproxy + Keepalived 或 Nginx,云上可以使用公有云的负载均衡器,然后在以下部分设置 MASTER_IP 和 APISERVER_NAME 为负载均衡器的地址(IP:6443) 和域名。

    # 设置hosts
    echo "127.0.0.1 $(hostname)" >> /etc/hosts
    export MASTER_IP=192.168.115.49
    export APISERVER_NAME=kuber4s.api
    echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts

    友情提示🙂🙂🙂:

    截止2020年01月29日,官方文档声明了使用 kubeadm 初始化 master 时,–config 这个参数是实验性质的,所以就不用了;我们用其他参数一样可以完成 master 的初始化。

    --config string   kubeadm 配置文件。 警告:配置文件的使用是试验性的。

    下面有不带注释的初始化命令,建议先查看带注释的每个参数对应的意义,确保与你的当前配置的环境是一致的,然后再执行初始化操作,避免踩雷。

    # 初始化 Control-plane/Master 节点
    kubeadm init \
        --apiserver-advertise-address 0.0.0.0 \
        # API 服务器所公布的其正在监听的 IP 地址,指定“0.0.0.0”以使用默认网络接口的地址
        # 切记只可以是内网IP,不能是外网IP,如果有多网卡,可以使用此选项指定某个网卡
        --apiserver-bind-port 6443 \
        # API 服务器绑定的端口,默认 6443
        --cert-dir /etc/kubernetes/pki \
        # 保存和存储证书的路径,默认值:"/etc/kubernetes/pki"
        --control-plane-endpoint kuber4s.api \
        # 为控制平面指定一个稳定的 IP 地址或 DNS 名称,
        # 这里指定的 kuber4s.api 已经在 /etc/hosts 配置解析为本机IP
        --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
        # 选择用于拉取Control-plane的镜像的容器仓库,默认值:"k8s.gcr.io"
        # 因 Google被墙,这里选择国内仓库
        --kubernetes-version 1.17.3 \
        # 为Control-plane选择一个特定的 Kubernetes 版本, 默认值:"stable-1"
        --node-name master01 \
        #  指定节点的名称,不指定的话为主机hostname,默认可以不指定
        --pod-network-cidr 10.10.0.0/16 \
        # 指定pod的IP地址范围
        --service-cidr 10.20.0.0/16 \
        # 指定Service的VIP地址范围
        --service-dns-domain cluster.local \
        # 为Service另外指定域名,默认"cluster.local"
        --upload-certs
        # 将 Control-plane 证书上传到 kubeadm-certs Secret

    不带注释的内容如下,如果初始化超时,可以修改DNS为8.8.8.8后重启网络服务再次尝试。

    kubeadm init \
     --apiserver-advertise-address 0.0.0.0 \
     --apiserver-bind-port 6443 \
     --cert-dir /etc/kubernetes/pki \
     --control-plane-endpoint kuber4s.api \
     --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers \
     --kubernetes-version 1.17.3 \
     --pod-network-cidr 10.10.0.0/16 \
     --service-cidr 10.20.0.0/16 \
     --service-dns-domain cluster.local \
     --upload-certs

    接下来这个过程有点漫长(初始化会下载镜像、创建配置文件、启动容器等操作),泡杯茶,耐心等待,你也可以执行 tailf /var/log/messages 来实时查看系统日志,观察 Master 的初始化进展,期间碰到一些报错不要紧张,可能只是暂时的错误,等待最终反馈的结果即可。

    如果初始化最终成功执行,你将看到如下信息:

    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/
    
    You can now join any number of the control-plane node running the following command on each as root:
    
      kubeadm join kuber4s.api:6443 --token 0j287q.jw9zfjxud8w85tis \
        --discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f \
        --control-plane --certificate-key 528b0b9f2861f8f02dfd4a59fc54ad21e42a7dea4dc5552ac24d9c650c5d4d80
    
    Please note that the certificate-key gives access to cluster sensitive data, keep it secret!
    As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use
    "kubeadm init phase upload-certs --upload-certs" to reload certs afterward.
    
    Then you can join any number of worker nodes by running the following on each as root:
    
    kubeadm join kuber4s.api:6443 --token 0j287q.jw9zfjxud8w85tis \
        --discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f

    为普通用户添加 kubectl 运行权限,命令内容在初始化成功后的输出内容中可以看到。

    mkdir -p $HOME/.kube
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config

    建议root用户也进行以上操作,作者使用的是root用户执行的初始化操作,然后在操作完成后查看集群状态的时候,出现如下错误:

    The connection to the server localhost:8080 was refused - did you specify the right host or port?

    这时候请备份好 kubeadm init 输出中的 kubeadm join 命令,因为将会需要这个命令来给集群添加节点。

    ⚠️⚠️⚠️提示:令牌是主节点和新添加的节点之间进行相互身份验证的,因此请确保其安全。任何人只要知道了这些令牌,就可以随便给您的集群添加节点。 你可以使用 kubeadm token 命令来查看、创建和删除这类令牌。

    4.2、安装 Pod 网络附加组件

    关于 Kubernetes 网络,建议读完这篇 文章,以及文末的其他链接,如这个

    集群必须安装Pod网络插件,以使Pod可以相互通信,只需要在Master节点操作,其他新加入的节点会自动创建相关pod。

    必须在任何应用程序之前部署网络组件。另外,在安装网络之前,CoreDNS将不会启动(你可以通过命令 kubectl get pods –all-namespaces|grep coredns 查看 CoreDNS 的状态)。

    # 查看 CoreDNS 的状态,并不是 Running 状态
    $ kubectl get pods --all-namespaces|grep coredns
    kube-system   coredns-7f9c544f75-bzksd    0/1   Pending   0     14m
    kube-system   coredns-7f9c544f75-mtrwq    0/1   Pending   0     14m

    kubeadm 支持多种网络插件,我们选择 Calico 网络插件(kubeadm 仅支持基于容器网络接口(CNI)的网络(不支持kubenet)。),默认情况下,它给出的pod的IP段地址是 192.168.0.0/16 ,如果你的机器已经使用了此IP段,就需要修改这个配置项,将其值改为在初始化 Master 节点时使用 kubeadm init –pod-network-cidr=x.x.x.x/x 的IP地址段,即我们上面配置的 10.10.0.0/16 ,大概在625行左右,操作如下:

    # 获取配置文件
    mkdir calico && cd calico
    wget https://docs.projectcalico.org/v3.8/manifests/calico.yaml
    
    # 修改配置文件
    # 找到 625 行左右的 192.168.0.0/16 ,并修改为我们初始化时配置的 10.10.0.0/16
    vim calico.yaml
    
    # 部署 Pod 网络组件
    kubectl apply -f calico.yaml

    稍等片刻查询 pod 详情,你也可以使用 watch 命令来实时查看 pod 的状态,等待 Pod 网络组件部署成功后,就可以看到一些信息了,包括 Pod 的 IP 地址信息,这个过程时间可能会有点长。

    watch -n 2 kubectl get pods --all-namespaces -o wide

    4.3、将 Worker 节点添加到 Kubernetes

    请首先确认 Worker 节点满足第一部分的环境说明,并且已经安装了 Docker 和 kubeadm、kubelet 、kubectl,并且已经启动 kubelet。export MASTER_IP=192.168.115.49 这里的是master的ip

    # 添加 Hosts 解析
    echo "127.0.0.1 $(hostname)" >> /etc/hosts
    export MASTER_IP=192.168.115.49
    export APISERVER_NAME=kuber4s.api
    echo "${MASTER_IP} ${APISERVER_NAME}" >> /etc/hosts

    将 Worker 节点添加到集群,这里注意,执行后可能会报错,有幸的话你会跳进这个坑,这是因为 Worker 节点加入集群的命令实际上在初始化 master 时已经有提示出来了,不过两小时后会删除上传的证书,所以如果你此时加入集群的时候提示证书相关的错误,请执行 kubeadm init phase upload-certs –upload-certs 重新加载证书。

    kubeadm join kuber4s.api:6443 --token 0y1dj2.ih27ainxwyib0911 \
        --discovery-token-ca-cert-hash sha256:5204b3e358a0d568e147908cba8036bdb63e604d4f4c1c3730398f33144fac61 \

    执行加入操作,你可能会发现卡着不动,大概率是因为令牌ID对此集群无效或已过 2 小时的有效期(通过执行 kubeadm join –v=5 来获取详细的加入过程,看到了内容为 ”token id “0y1dj2” is invalid for this cluster or it has expired“ 的提示),接下来需要在 Master 上通过 kubeadm token create 来创建新的令牌。

    $ kubeadm token create --print-join-command
    W0129 19:10:04.842735   15533 validation.go:28] Cannot validate kube-proxy config - no validator is available
    W0129 19:10:04.842808   15533 validation.go:28] Cannot validate kubelet config - no validator is available
    # 输出结果如下
    kubeadm join kuber4s.api:6443 --token 1hk9bc.oz7f3lmtbzf15x9b     --discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f

    在 Worker 节点上重新执行加入集群命令

    kubeadm join kuber4s.api:6443 \
        --token 1hk9bc.oz7f3lmtbzf15x9b \
        --discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f

    接下来在Master上查看 Worker 节点加入的状况,直到 Worker 节点的状态变为 Ready 便证明加入成功,这个过程可能会有点漫长,30 分钟以内都算正常的,主要看你网络的情况或者说拉取镜像的速度;另外不要一看到 /var/log/messages 里面报错就慌了,那也得看具体报什么错,看不懂就稍微等一下,一般在 Master 上能看到已经加入(虽然没有Ready)就没什么问题。

    watch kubectl get nodes -o wide

    4.4、添加 Master 节点

    需要至少2个CPU核心,否则会报错

    kubeadm join kuber4s.api:6443 \
        --token 1hk9bc.oz7f3lmtbzf15x9b \
        --discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f \
        --control-plane --certificate-key 5253fc7e9a4e6204d0683ed2d60db336b3ff64ddad30ba59b4c0bf40d8ccadcd

    错误

    error execution phase preflight: couldn't validate the identity of the API Server: abort connecting to API servers after timeout of 5m0s To see the stack trace of this error execute with --v=5 or higher

    解决:上诉步骤都做了的话,一般都是防火墙和安全组等端口问题

     

    4.5、补充内容,初始化 Kubernetes 主节点,移除 worker 节点,恢复到之前状态

    • kubeadm init 初始化 Kubernetes 主节点
    • kubeadm token 管理 kubeadm join 的令牌
    • kubeadm reset 将 kubeadm init 或 kubeadm join 对主机的更改恢复到之前状态,一般与 -f 参数使用

    移除 worker 节点

    正常情况下,你无需移除 worker 节点,如果要移除,在准备移除的 worker 节点上执行

    kubeadm reset -f

    或者在 Control-plane 上执行

    kubectl delete node nodename
    • 将 nodename 替换为要移除的 worker 节点的名字
    • worker 节点的名字可以通过在 Control-plane 上执行 kubectl get nodes 命令获得

    五、Kubernetes 高可用集群

    5.1、环境说明

    如果你使用的是以上方法部署你的 Kubernetes 集群,想在当前基础上进行高可用集群的创建,则可以按照下面的步骤继续进行。

    值得注意的是,这里没有将ETCD放在Master外的机器上,而是使用默认的架构,即官方的 Stacked etcd topology 方式的集群

    你需要至少 3 台 Master 节点和 3 台 Worker 节点,或者更多的机器,但要保证是 Master 和 Worker 节点数都是奇数的,以防止 leader 选举时出现脑裂状况。

    机器名称 机器IP 工作内容
    master01 192.168.115.49 master、etcd
    master02 192.168.115.41 master、etcd
    master03 192.168.115.42 master、etcd
    node01 192.168.115.46 worker
    node02 192.168.115.47 worker
    node03 192.168.115.48 worker
    nfs 192.168.115.50 存储

    5.2、高可用扩展

    Kubernetes 的高可用扩展其实挺简单,你只需要将不同的 Master 和 Worker 节点加入到集群中就行了。加入的指令在你初始化集群时已经给出了。

    • 添加 Master 节点:

    需要至少 2 个 CPU 核心,否则会报错

    kubeadm join kuber4s.api:6443 \
     --token 1hk9bc.oz7f3lmtbzf15x9b \
     --discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f \
     --control-plane --certificate-key 5253fc7e9a4e6204d0683ed2d60db336b3ff64ddad30ba59b4c0bf40d8ccadcd
    • 添加 Worker 节点

    在 Worker 节点上重新执行加入集群命令

    kubeadm join kuber4s.api:6443 \
    --token 1hk9bc.oz7f3lmtbzf15x9b \
    --discovery-token-ca-cert-hash sha256:5e8bcad5ec97c1025e8044f4b8fd0a4514ecda4bac2b3944f7f39ccae9e4921f

    六、安装 KubeSphere

    6.1、KubeSphere简介

    Kubernetes 官方有提供一套 Dashboard,但是我这里选择功能更强大的 KubeSphere,以下内容引用自 KubeSphere 官网:

    KubeSphere 是在 Kubernetes 之上构建的以应用为中心的容器平台,提供简单易用的操作界面以及向导式操作方式,在降低用户使用容器调度平台学习成本的同时,极大减轻开发、测试、运维的日常工作的复杂度,旨在解决 Kubernetes 本身存在的存储、网络、安全和易用性等痛点。除此之外,平台已经整合并优化了多个适用于容器场景的功能模块,以完整的解决方案帮助企业轻松应对敏捷开发与自动化运维、DevOps、微服务治理、灰度发布、多租户管理、工作负载和集群管理、监控告警、日志查询与收集、服务与网络、应用商店、镜像构建与镜像仓库管理和存储管理等多种场景。后续版本将提供和支持多集群管理、大数据、AI 等场景。

    6.2、安装要求

    KubeSphere 支持直接在 Linux 上部署集群,也支持在 Kubernetes 上部署,我这里选择后者,基本的要求如下:

    6.3、安装 Helm

    6.3.1、Helm 简介

    Helm 基本思想如图所示

    以下内容引用自 此篇文章

    Helm 基本概念

    Helm 可以理解为 Kubernetes 的包管理工具,可以方便地发现、共享和使用为Kubernetes构建的应用,它包含几个基本概念:

    • Chart:一个 Helm 包,其中包含了运行一个应用所需要的镜像、依赖和资源定义等,还可能包含 Kubernetes 集群中的服务定义
    • Release: 在 Kubernetes 集群上运行的 Chart 的一个实例。在同一个集群上,一个 Chart 可以安装很多次。每次安装都会创建一个新的 release。例如一个 MySQL Chart,如果想在服务器上运行两个数据库,就可以把这个 Chart 安装两次。每次安装都会生成自己的 Release,会有自己的 Release 名称。
    • Repository:用于发布和存储 Chart 的仓库。

    6.3.2、Helm安装

    安装过程如下 迅雷可以下载tar包

    # 创建部署目录并下载Helm
    mkdir tiller
    cd tiller
    
    # 先使用官方的方式安装,如果安装不了,可以看到下载文件的地址,然后手动下载解压
    curl -L https://git.io/get_helm.sh | bash
    # 获取到下载地址后,想办法下载
    wget https://get.helm.sh/helm-v2.16.3-linux-amd64.tar.gz
    tar zxf helm-v2.16.3-linux-amd64.tar.gz
    mv linux-amd64/helm /usr/local/bin/helm
    
    # 验证
    helm version

    部署 Tiller,即 Helm 的服务端。先创建 SA

    # yaml文件如下  格式一定要整整齐齐
    $ cat /root/tiller/helm-rbac.yaml
    
    
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: tiller
      namespace: kube-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: tiller
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
      - kind: ServiceAccount
        name: tiller
        namespace: kube-system

    创建 RBAC:

    kubectl apply -f helm-rbac.yaml

    初始化,这个过程可能不会成功,具体接着往下看

    helm init --service-account=tiller --history-max 300

    检查初始化的情况,不出意外的话,墙内用户看pod详情可以看到获取不到镜像的错误。

    kubectl get deployment tiller-deploy -n kube-system

    如果一直获取不到镜像,可以通过更换到Azure中国镜像源来解决,操作步骤如下:

    # 编辑 deploy
    kubectl edit deploy tiller-deploy -n kube-system
    # 查找到image地址,替换为如下地址,保存退出
    gcr.azk8s.cn/kubernetes-helm/tiller:v2.16.3

    或者改成image: sapcc/tiller:v2.16.3

    接下来稍等片刻,再次查看deployment和pod详情,就正常了

    kubectl get deployment tiller-deploy -n kube-system

    6.4、安装 StorageClass

    Kubernetes 支持多种 StorageClass,我这选择 NFS 作为集群的 StorageClass。

    参考地址:https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client

    6.4.1、下载所需文件

    下载所需文件,并进行内容调整

    mkdir nfsvolume && cd nfsvolume
    for file in class.yaml deployment.yaml rbac.yaml ; do wget https://raw.githubusercontent.com/kubernetes-incubator/external-storage/master/nfs-client/deploy/$file ; done

    修改 deployment.yaml 中的两处 都是NFS 服务器 IP 和目录,例如nfs的服务器ip是192.168.115.50

    ...
              env:
                - name: PROVISIONER_NAME
                  value: fuseim.pri/ifs
                - name: NFS_SERVER
                  value: 192.168.115.50
                - name: NFS_PATH
                  value: /data/k8s
          volumes:
            - name: nfs-client-root
              nfs:
                server: 192.168.115.50
                path: /data/k8s

    6.4.2、部署创建

    具体的说明可以去官网查看。

    kubectl create -f rbac.yaml
    kubectl create -f class.yaml
    kubectl create -f deployment.yaml

    启动了,等一会儿

    如果日志中看到“上有坏超级块”,请在集群内所有机器上安装nfs-utils并启动。

    yum -y install nfs-utils
    systemctl start nfs-utils
    systemctl enable nfs-utils
    rpcinfo -p

    查看storageclass

    $ kubectl get storageclass
    NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    managed-nfs-storage fuseim.pri/ifs Delete Immediate false 10m

    6.4.3、标记一个默认的 StorageClass

    操作命令格式如下

    kubectl patch storageclass 名字 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

    查看标签
    kubectl  get sc
    
    如storageclass的name 是managed-nfs-storage
    kubectl patch storageclass managed-nfs-storage -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

    请注意,最多只能有一个 StorageClass 能够被标记为默认。

    验证标记是否成功

    $ kubectl get storageclass
    NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
    managed-nfs-storage (default) fuseim.pri/ifs Delete Immediate false 12m

    6.5、部署 KubeSphere  完整版太大了 最小化半天报错  换kuboard试试

    过程很简单,如果你的机器资源足够,建议你进行完整安装,操作步骤如下。如果你的资源不是很充足,则可以进行最小化安装,参考地址。我当然是选择完整安装了,香!

    # 下载 yaml 文件
    mkdir kubesphere && cd kubesphere
    wget https://raw.githubusercontent.com/kubesphere/ks-installer/master/kubesphere-complete-setup.yaml
    # 部署 KubeSphere
    kubectl apply -f kubesphere-complete-setup.yaml

    这个过程根据你实际网速,实际使用时间长度有所不同。你可以通过如下命令查看实时的日志输出。

    kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l app=ks-install -o jsonpath='{.items[0].metadata.name}') -f

    当你看到如下日志输出,证明你的 KubeSphere 部署成功

    **************************************************
    task monitoring status is successful
    task notification status is successful
    task devops status is successful
    task alerting status is successful
    task logging status is successful
    task openpitrix status is successful
    task servicemesh status is successful
    total: 7     completed:7
    **************************************************
    #####################################################
    ###              Welcome to KubeSphere!           ###
    #####################################################
    
    Console: http://192.168.115.49:30880
    Account: admin
    Password: P@88w0rd
    #####################################################

    确认 Pod 都正常运行后,可使用IP:30880访问 KubeSphere UI 界面,默认的集群管理员账号为admin/P@88w0rd,Enjoy it,😏!

     

     

    以下一键部署

    环境信息

    主机名 IP地址
    master0 192.168.0.2
    master1 192.168.0.3
    master2 192.168.0.4
    node0 192.168.0.5

    服务器密码:123456

    kubernetes高可用安装教程
    只需要准备好服务器,在任意一台服务器上执行下面命令即可

    # 下载并安装sealos, sealos是个golang的二进制工具,直接下载拷贝到bin目录即可
    wget https://github.com/fanux/sealos/releases/download/v3.0.1/sealos && \
        chmod  x sealos && mv sealos /usr/bin 
            
    # 下载离线资源包
    wget https://sealyun.oss-cn-beijing.aliyuncs.com/413bd3624b2fb9e466601594b4f72072-1.17.0/kube1.17.0.tar.gz
    
    # 安装一个三master的kubernetes集群
    sealos init --passwd 123456 \
        --master 192.168.0.2  --master 192.168.0.3  --master 192.168.0.4  \
        --node 192.168.0.5 \
        --pkg-url  /root/kube1.17.0.tar.gz \
        --version v1.17.0
    •  

    参数含义

    参数名 含义 示例
    passwd 服务器密码 123456
    master k8s master节点IP地址 192.168.0.2
    node k8s node节点IP地址 192.168.0.3
    pkg-url 离线资源包地址,支持下载到本地,或者一个远程地址 /root/kube1.16.0.tar.gz
    version 资源包对应的版本 v1.16.0

    就没有然后了

     

    从零亲测 一键暂未

    参考

    https://www.kubernetes.org.cn/7315.html

    https://blog.csdn.net/github_35614077/article/details/103486213

    展开全文
  • 系列一中忘了说明,用Kubernetes部署大数据容器平台,有一个很大的好处是压根不用操心容器间的网络通信,不管是同一物理服务器内,还是跨物理服务器间的网络通信,你都不用操心,只需要把容器间互相关心的端口暴露好...

    系列一中忘了说明,用Kubernetes部署大数据容器平台,有一个很大的好处是压根不用操心容器间的网络通信,不管是同一物理服务器内,还是跨物理服务器间的网络通信,你都不用操心,只需要把容器间互相关心的端口暴露好,把容器间的service name映射好,就OK了。

    本篇教大家部署Hadoop 2.7.3集群,暂时没有做HA和联邦: Docker适合封装无状态的、单进程的应用程序,如果用它来部署Hadoop分布式集群,还是比较复杂的,主要考虑几个问题:

    • 1,需要制作几个镜像?
    • 2,哪些配置属于通用的,可以直接打包到镜像中?
    • 3,会变更的配置,如何在容器启动时自动的、灵活的替换?
    • 4,哪些服务端口需要暴露?
    • 5,哪些目录需要持久化?
    • 6,NameNode的Format怎么实现和如何避免重复Format?
    • 7,用哪些脚本来启动哪些服务?
    • 8,需要提前设置哪些环境变量?
    • 9,Pod间的依赖和启动顺序如何控制? 等等等。

    物理拓扑及Hadoop集群角色如下:

    服务器地址角色
    yuyan210.0.8.182Docker镜像制作、K8s yaml脚本编辑、kubectl客户端
    HARBOR10.10.4.57私有镜像库
    ksp-110.10.4.56NameNode、DataNode、ResourceManager、NodeManager
    ksp-210.10.4.57DataNode、NodeManager
    ksp-510.10.4.60DataNode、NodeManager

    1,先制作一个基础镜像: 包含Ubuntu 16.04 LTS、jdk1.8.0_111、各类常用工具(net-tools、iputils、vim、wget)、SSH免密及开机启动、时钟与宿主机同步、无防火墙等。 该镜像PUSH到HARBOR私有镜像库,以便后面制作Hadoop容器时引用它。 制作过程略过,想用的话直接从链接下载即可: Ubuntu基础镜像

    2,鉴于Hadoop2.x版本有YARN的存在,所以制作两个镜像,称为: 主镜像,包含:NameNode、ResourceManager守护进程; 从镜像,包含:DataNode、NodeManager守护进程。

    新建一个hadoop2.7.3目录,结构如下:

    • 从官网下载hadoop-2.7.3.tar.gz;
    • 取出其/etc/hadoop中的配置,放入到conf文件中,修改:core-site.xml、hdfs-site.xml、mapred-site.xml、yarn-site.xml、并将slaves清空;
    • docker-entrypoint-namenode.sh 制作主镜像时,重命名为docker-entrypoint.sh,启动相关服务进程;
    • docker-entrypoint-datanode.sh 制作从镜像时,重命名为docker-entrypoint.sh,启动相关服务进程;
    • Dockerfile,定义环境变量、申明端口、拷贝及替换文件等操作。

    如下几个目录是需要持久化的,在后面的yaml文件中体现: core-site.xml:hadoop.tmp.dir hdfs-site.xml:dfs.namenode.name.dir hdfs-site.xml:dfs.namenode.data.dir

    哪些配置文件作为通用文件,哪些配置文件的内容需要动态替换,NameNode 什么情况下做Format,主、从镜像各启动什么服务等,请自行参考链接中的脚本: Hadoop的两个镜像及相关脚本

    制作好镜像,并推送到HARBOR私有镜像库中,以便K8s编排容器时使用:

    ➜  hadoop2.7.3 mv docker-entrypoint-namenode.sh docker-entrypoint.sh
    ➜  hadoop2.7.3 sudo docker build -t hadoop-2.7.3-namenode-resourcemanager:0.0.1 .
    ➜  hadoop2.7.3 sudo docker tag hadoop-2.7.3-namenode-resourcemanager:0.0.1  registry.k8s.intra.knownsec.com/bigdata/hadoop-2.7.3-namenode-resourcemanager:0.0.1
    ➜  hadoop2.7.3 sudo docker push registry.k8s.intra.knownsec.com/bigdata/hadoop-2.7.3-namenode-resourcemanager:0.0.1
    ➜  hadoop2.7.3 mv docker-entrypoint-datanode.sh docker-entrypoint.sh
    ➜  hadoop2.7.3 sudo docker build -t hadoop-2.7.3-datanode-nodemanager:0.0.1 .
    ➜  hadoop2.7.3 sudo docker tag hadoop-2.7.3-datanode-nodemanager:0.0.1  registry.k8s.intra.knownsec.com/bigdata/hadoop-2.7.3-datanode-nodemanager:0.0.1
    ➜  hadoop2.7.3 sudo docker push registry.k8s.intra.knownsec.com/bigdata/hadoop-2.7.3-datanode-nodemanager:0.0.1

    相关镜像已经推送到私有镜像库:


    3,经过上述的步骤,主、从两个镜像就制作好了,下面,新生成一个
    hadoop文件夹,用来编写yaml文件,并执行K8s编排任务:


    由于容器间需要相互通信,且需要对外提供服务,所以我们仍然采用Deployment方式来编排,每个Pod启动一个容器,Pod间暴露相关接口,每个Pod都可以对外提供服务,启动主镜像的Pod使用0.0.0.0监听自己的端口,启动从镜像的其他Pod使用主Pod的service name,作为目的hostname,持久化的 细节及动态替换hostname的细节,请参考yaml文件:
    K8s编排Hadoop集群的yaml文件

    按照顺序启动Pod(这个过程可以做成脚本,一键执行):

    ➜  hadoop kubectl create -f hadoop-namenode-resourcemanager.yaml --validate=false
    ➜  hadoop kubectl create -f hadoop-datanode-nodemanager01.yaml --validate=false
    ➜  hadoop kubectl create -f hadoop-datanode-nodemanager02.yaml --validate=false
    ➜  hadoop kubectl create -f hadoop-datanode-nodemanager05.yaml --validate=false

    当主镜像的Pod要更换service name时,只需要替换从镜像Pod yaml中的ConfigMap hostname值即可

    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: hdp-2-cm
    data:
      hostname: "hdp-1-svc"
    ---

    验证:

    • 可以看到4个Pod分配到了指定的物理服务器上:

    • 可以看到每个Pod对外提供的端口:

    • 使用ksp-1主机的IP加hdp-1-2386450527-9x6b9暴露的50070:30980/TCP,可以看到HDFS Web中DataNode的情况:

    • 使用ksp-1主机的IP加hdp-1-2386450527-9x6b9暴露的8088:32326/TCP,可以看到YARN Web中NodeManager的情况:

    补充:
    对上述操作部署好的hadoop集群进行简单验证,hdfs的基本功能正常,执行一个mapreduce wordcount用例时,出现错误提示:

    hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount file:///hadoop-2.7.3/NOTICE.txt file:///hadoop-2.7.3/output2
    17/07/03 05:32:10 INFO client.RMProxy: Connecting to ResourceManager at hdp-1-svc/12.0.112.23:8032
    17/07/03 05:32:11 INFO input.FileInputFormat: Total input paths to process : 1
    17/07/03 05:32:12 INFO mapreduce.JobSubmitter: number of splits:1
    17/07/03 05:32:12 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1498909283586_0006
    17/07/03 05:32:12 INFO impl.YarnClientImpl: Submitted application application_1498909283586_0006
    17/07/03 05:32:12 INFO mapreduce.Job: The url to track the job: http://hdp-1-2386450527-9x6b9:8088/proxy/application_1498909283586_0006/
    17/07/03 05:32:12 INFO mapreduce.Job: Running job: job_1498909283586_0006
    17/07/03 05:32:18 INFO mapreduce.Job: Job job_1498909283586_0006 running in uber mode : false
    17/07/03 05:32:18 INFO mapreduce.Job:  map 0% reduce 0%
    17/07/03 05:32:19 INFO mapreduce.Job: Task Id : attempt_1498909283586_0006_m_000000_0, Status : FAILED
    Container launch failed for container_1498909283586_0006_01_000002 : java.lang.IllegalArgumentException: java.net.UnknownHostException: hdp-2-1789154958-g0njg
        at org.apache.hadoop.security.SecurityUtil.buildTokenService(SecurityUtil.java:377)
        at org.apache.hadoop.security.SecurityUtil.setTokenService(SecurityUtil.java:356)
        at org.apache.hadoop.yarn.util.ConverterUtils.convertFromYarn(ConverterUtils.java:238)
        at org.apache.hadoop.yarn.client.api.impl.ContainerManagementProtocolProxy$ContainerManagementProtocolProxyData.newProxy(ContainerManagementProtocolProxy.java:266)
        at org.apache.hadoop.yarn.client.api.impl.ContainerManagementProtocolProxy$ContainerManagementProtocolProxyData.<init>(ContainerManagementProtocolProxy.java:244)
        at org.apache.hadoop.yarn.client.api.impl.ContainerManagementProtocolProxy.getProxy(ContainerManagementProtocolProxy.java:129)
        at org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl.getCMProxy(ContainerLauncherImpl.java:409)
        at org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl$Container.launch(ContainerLauncherImpl.java:138)
        at org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl$EventProcessor.run(ContainerLauncherImpl.java:375)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
    Caused by: java.net.UnknownHostException: hdp-2-1789154958-g0njg
        ... 12 more

    这个错误的原因:
    因为创建Pod时,会给每个容器随机分配一个hostname,我们前面是使用svc-name来保证服务间的通信,但是mapreduce执行时,使用的是hostname,而每台容器启动后,/etc/hosts中是仅有自己的主机名和ip的映射,是不包含其他容器的。而且,也无法动态的向/etc/hosts里面增加其他容器的主机名和ip的映射,所以分配ApplicationMaster时,无法响应客户端的请求。

    修复起来较麻烦:
    需要修改主、从镜像的dockerfile,docker-entrypoint.sh,重新制作主,从镜像,然后修改yaml,之后按照原有流程启动即可。
    修改方案就是使用Headless Service,不再使用cluster ip,而是在 Pod之间直接使用各容器的私有IP,并在yaml指定Pod启动的容器的主机名,和svc-name配置成一致的。不过,这种方式下,外网不能直接访问集群了(比如外网的一个用户想登陆HDFS的web ui),需要启动一个Nginx容器,由它做一个DNS代理,能够让外网访问集群IP和端口即可,请自行搜索解决方案,这里不再描述。

    相关修改如下,修改之后如何重新搭建集群,请参考前文。另,yaml我只修改了2个,其他节点的yaml照着修改就行了:
    Dockerfile:

    FROM registry.k8s.intra.knownsec.com/bigdata/ubuntu16.04_jdk1.8.0_111:0.0.2
    MAINTAINER Wang Liang <wangl8@knownsec.com>
    
    ARG DISTRO_NAME=hadoop-2.7.3
    ARG DISTRO_NAME_DIR=/hadoop-2.7.3
    
    ENV HADOOP_HOME=$DISTRO_NAME_DIR
    ENV HADOOP_PREFIX=$DISTRO_NAME_DIR
    ENV HADOOP_CONF_DIR=$HADOOP_PREFIX/etc/hadoop
    ENV YARN_CONF_DIR=$HADOOP_PREFIX/etc/hadoop
    ENV HADOOP_TMP_DIR=$HADOOP_HOME/tmp
    ENV HADOOP_DFS_DIR=$HADOOP_HOME/dfs
    ENV HADOOP_DFS_NAME_DIR=$HADOOP_DFS_DIR/name
    ENV HADOOP_DFS_DATA_DIR=$HADOOP_DFS_DIR/data
    ENV HADOOP_LOGS=$HADOOP_HOME/logs
    ENV Master=localhost
    ENV USER=root
    
    USER root
    
    # Hdfs ports
    EXPOSE 9000 50010 50020 50070 50075 50090 31010 8020
    
    # Mapred ports
    EXPOSE 19888 10020
    
    #Yarn ports
    EXPOSE 8030 8031 8032 8033 8040 8042 8088
    
    #Other ports
    EXPOSE 49707 2122
    
    ADD hadoop-2.7.3.tar.gz /
    WORKDIR $DISTRO_NAME_DIR
    #ENV ZOO_USER=zookeeper \
    #    ZOO_CONF_DIR=/conf \
    #    ZOO_DATA_DIR=/data \
    #    ZOO_UI_DIR=/zkui \
    #    ZOO_DATA_LOG_DIR=/datalog \
    #    ZOO_PORT=2181 \
    #    ZOO_TICK_TIME=2000 \
    #    ZOO_INIT_LIMIT=5 \
    #    ZOO_SYNC_LIMIT=2
    
    # Add a user and make dirs
    #RUN set -x \
    #    && adduser -D "$ZOO_USER" \
    #    && mkdir -p "$ZOO_DATA_LOG_DIR" "$ZOO_DATA_DIR" "$ZOO_CONF_DIR" \
    #    && chown "$ZOO_USER:$ZOO_USER" "$ZOO_DATA_LOG_DIR" "$ZOO_DATA_DIR" "$ZOO_CONF_DIR"
    
    #ARG DISTRO_NAME=hadoop-2.7.3
    
    RUN rm -r -f $HADOOP_CONF_DIR
    RUN mkdir -p "$HADOOP_TMP_DIR" "$HADOOP_DFS_NAME_DIR" "$HADOOP_DFS_DATA_DIR" "$HADOOP_LOGS"
    ADD conf $HADOOP_CONF_DIR
    
    COPY conf /conf_tmp
    
    ENV PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
    
    # Download Apache Zookeeper, verify its PGP signature, untar and clean up
    #RUN set -x \
    #    && tar -xzf "$DISTRO_NAME.tar.gz"
    
    #WORKDIR $DISTRO_NAME
    
    #VOLUME ["$ZOO_DATA_DIR", "$ZOO_DATA_LOG_DIR"]
    
    #EXPOSE $ZOO_PORT 2888 3888
    
    #ENV PATH=$PATH:/$DISTRO_NAME/bin:$ZOO_UI_DIR \
    #    ZOOCFGDIR=$ZOO_CONF_DIR
    
    COPY docker-entrypoint.sh /
    ENTRYPOINT ["/docker-entrypoint.sh"]

    docker-entrypoint-namenode.sh:

    #!/bin/bash
    source /etc/environment
    source ~/.bashrc
    source /etc/profile
    export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
    
    
    sed "s/HOSTNAME/"$Master"/g"    /conf_tmp/core-site.xml > $HADOOP_CONF_DIR/core-site.xml
    sed "s/HOSTNAME/"$Master"/g"    /conf_tmp/mapred-site.xml > $HADOOP_CONF_DIR/mapred-site.xml
    sed "s/HOSTNAME/"$Master"/g"    /conf_tmp/yarn-site.xml > $HADOOP_CONF_DIR/yarn-site.xml
    
    
    if [ "`ls -A $HADOOP_DFS_NAME_DIR`" = "" ]; then
    echo "$DIRECTORY is indeed empty"
    $HADOOP_PREFIX/bin/hdfs namenode -format
    else
    echo "$DIRECTORY is not empty"
    fi
    
    $HADOOP_PREFIX/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR start namenode
    #$HADOOP_PREFIX/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR start datanode
    
    $HADOOP_PREFIX/sbin/yarn-daemon.sh --config $HADOOP_CONF_DIR start resourcemanager
    #$HADOOP_PREFIX/sbin/yarn-daemon.sh --config $HADOOP_CONF_DIR start nodemanager
    $HADOOP_PREFIX/sbin/mr-jobhistory-daemon.sh   start historyserver
    
    
    
    #exec nohup /etc/init.d/ssh start &
    /etc/init.d/ssh start
    #exec /bin/bash
    while true; do sleep 1000; done

    docker-entrypoint-datanode.sh:

    #!/bin/bash
    source /etc/environment
    source ~/.bashrc
    source /etc/profile
    export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
    
    
    sed "s/HOSTNAME/"$Master"/g"    /conf_tmp/core-site.xml > $HADOOP_CONF_DIR/core-site.xml
    sed "s/HOSTNAME/"$Master"/g"    /conf_tmp/mapred-site.xml > $HADOOP_CONF_DIR/mapred-site.xml
    sed "s/HOSTNAME/"$Master"/g"    /conf_tmp/yarn-site.xml > $HADOOP_CONF_DIR/yarn-site.xml
    
    
    #if [ "`ls -A $HADOOP_DFS_NAME_DIR`" = "" ]; then
    #echo "$DIRECTORY is indeed empty"
    #$HADOOP_PREFIX/bin/hdfs namenode -format
    #else
    #echo "$DIRECTORY is not empty"
    #fi
    
    #$HADOOP_PREFIX/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR start namenode
    $HADOOP_PREFIX/sbin/hadoop-daemon.sh --config $HADOOP_CONF_DIR start datanode
    
    #$HADOOP_PREFIX/sbin/yarn-daemon.sh --config $HADOOP_CONF_DIR start resourcemanager
    $HADOOP_PREFIX/sbin/yarn-daemon.sh --config $HADOOP_CONF_DIR start nodemanager
    #$HADOOP_PREFIX/sbin/mr-jobhistory-daemon.sh   start historyserver
    
    #exec nohup /etc/init.d/ssh start &
    /etc/init.d/ssh start
    #exec /bin/bash
    while true; do sleep 1000; done

    hadoop-namenode-resourcemanager.yaml :

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: hdp-1-svc
      labels:
        app: hdp-1-svc
    spec:
      clusterIP: None  #注意这里,要写成None,才能使用headless service
      ports:
      - port: 9000
        name: hdfs
      - port: 50070
        name: hdfsweb
      - port: 19888
        name: jobhistory
      - port: 8088
        name: yarn
      - port: 50010
        name: hdfs2
      - port: 50020
        name: hdfs3
      - port: 50075
        name: hdfs5
      - port: 50090
        name: hdfs6
      - port: 10020
        name: mapred2
      - port: 8030
        name: yarn1
      - port: 8031
        name: yarn2
      - port: 8032
        name: yarn3
      - port: 8033
        name: yarn4
      - port: 8040
        name: yarn5
      - port: 8042
        name: yarn6
      - port: 49707
        name: other1
      - port: 2122
        name: other2
      - port: 31010
        name: hdfs7
      - port: 8020
        name: hdfs8
    
      selector:
        app: hdp-1
      type: NodePort
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: hdp-1-cm
    data:
      master: "0.0.0.0"
      hostname: "hdp-1-svc"
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: hdp-1
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: hdp-1
        spec:
          hostname: hdp-1-svc  #指定容器启动时的主机名,配置成svc-name即可
          nodeSelector:
            zk: zk-1
          containers:
          - name: myhadoop-nn-rm
            imagePullPolicy: Always
            image: registry.k8s.intra.knownsec.com/bigdata/hadoop-2.7.3-namenode-resourcemanager:0.0.1
            securityContext:
              privileged: true
            resources:
              requests:
                memory: "2Gi"
                cpu: "500m"
            ports:
            - containerPort: 9000
              name: hdfs
            - containerPort: 50010
              name: hdfs2
            - containerPort: 50020
              name: hdfs3
            - containerPort: 50070
              name: hdfsweb
            - containerPort: 50075
              name: hdfs5
            - containerPort: 50090
              name: hdfs6
            - containerPort: 19888
              name: jobhistory
            - containerPort: 10020
              name: mapred2
            - containerPort: 8030
              name: yarn1
            - containerPort: 8031
              name: yarn2
            - containerPort: 8032
              name: yarn3
            - containerPort: 8033
              name: yarn4
            - containerPort: 8040
              name: yarn5
            - containerPort: 8042
              name: yarn6
            - containerPort: 8088
              name: yarn
            - containerPort: 49707
              name: other1
            - containerPort: 2122
              name: other2
            - containerPort: 31010
              name: hdfs7
            - containerPort: 8020
              name: hdfs8
            env:
            - name: Master
              valueFrom:
                configMapKeyRef:
                    name: hdp-1-cm
                    key: master
            - name: HOSTNAME
              valueFrom:
                configMapKeyRef:
                    name: hdp-1-cm
                    key: hostname
    #        readinessProbe:
    #          exec:
    #            command:
    #            - "zkok.sh"
    #          initialDelaySeconds: 10
    #          timeoutSeconds: 5
    #        livenessProbe:
    #          exec:
    #            command:
    #            - "zkok.sh"
    #          initialDelaySeconds: 10
    #          timeoutSeconds: 5
            volumeMounts:
            - name: name
              mountPath: /hadoop-2.7.3/dfs/name
            - name: data
              mountPath: /hadoop-2.7.3/dfs/data
            - name: tmp
              mountPath: /hadoop-2.7.3/tmp
            - name: logs
              mountPath: /hadoop-2.7.3/logs
          volumes:
          - name: name
            hostPath:
              path: /home/data/bjrddata/hadoop/name021
          - name: data
            hostPath:
              path: /home/data/bjrddata/hadoop/data021
          - name: tmp
            hostPath:
              path: /home/data/bjrddata/hadoop/tmp021
          - name: logs
            hostPath:
              path: /home/data/bjrddata/hadoop/logs021

    hadoop-datanode-nodemanager01.yaml :

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: hdp-2-svc
      labels:
        app: hdp-2-svc
    spec:
      clusterIP: None
      ports:
      - port: 9000
        name: hdfs
      - port: 50070
        name: hdfsweb
      - port: 19888
        name: jobhistory
      - port: 8088
        name: yarn
      - port: 50010
        name: hdfs2
      - port: 50020
        name: hdfs3
      - port: 50075
        name: hdfs5
      - port: 50090
        name: hdfs6
      - port: 10020
        name: mapred2
      - port: 8030
        name: yarn1
      - port: 8031
        name: yarn2
      - port: 8032
        name: yarn3
      - port: 8033
        name: yarn4
      - port: 8040
        name: yarn5
      - port: 8042
        name: yarn6
      - port: 49707
        name: other1
      - port: 2122
        name: other2
      - port: 31010
        name: hdfs7
      - port: 8020
        name: hdfs8
    
      selector:
        app: hdp-2
      type: NodePort
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: hdp-2-cm
    data:
      master: "hdp-1-svc"
      hostname: "hdp-2-svc"
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: hdp-2
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: hdp-2
        spec:
          hostname: hdp-2-svc
          nodeSelector:
            zk: zk-1
          containers:
          - name: myhadoop-dn-nm
            imagePullPolicy: Always
            image: registry.k8s.intra.knownsec.com/bigdata/hadoop-2.7.3-datanode-nodemanager:0.0.1
            securityContext:
              privileged: true
            resources:
              requests:
                memory: "2Gi"
                cpu: "500m"
            ports:
            - containerPort: 9000
              name: hdfs
            - containerPort: 50010
              name: hdfs2
            - containerPort: 50020
              name: hdfs3
            - containerPort: 50070
              name: hdfsweb
            - containerPort: 50075
              name: hdfs5
            - containerPort: 50090
              name: hdfs6
            - containerPort: 19888
              name: jobhistory
            - containerPort: 10020
              name: mapred2
            - containerPort: 8030
              name: yarn1
            - containerPort: 8031
              name: yarn2
            - containerPort: 8032
              name: yarn3
            - containerPort: 8033
              name: yarn4
            - containerPort: 8040
              name: yarn5
            - containerPort: 8042
              name: yarn6
            - containerPort: 8088
              name: yarn
            - containerPort: 49707
              name: other1
            - containerPort: 2122
              name: other2
            - containerPort: 31010
              name: hdfs7
            - containerPort: 8020
              name: hdfs8
            env:
            - name: Master
              valueFrom:
                configMapKeyRef:
                    name: hdp-2-cm
                    key: master
            - name: HOSTNAME
              valueFrom:
                configMapKeyRef:
                    name: hdp-2-cm
                    key: hostname
    #        readinessProbe:
    #          exec:
    #            command:
    #            - "zkok.sh"
    #          initialDelaySeconds: 10
    #          timeoutSeconds: 5
    #        livenessProbe:
    #          exec:
    #            command:
    #            - "zkok.sh"
    #          initialDelaySeconds: 10
    #          timeoutSeconds: 5
            volumeMounts:
            - name: name
              mountPath: /hadoop-2.7.3/dfs/name
            - name: data
              mountPath: /hadoop-2.7.3/dfs/data
            - name: tmp
              mountPath: /hadoop-2.7.3/tmp
            - name: logs
              mountPath: /hadoop-2.7.3/logs
          volumes:
          - name: name
            hostPath:
              path: /home/data/bjrddata/hadoop/name022
          - name: data
            hostPath:
              path: /home/data/bjrddata/hadoop/data022
          - name: tmp
            hostPath:
              path: /home/data/bjrddata/hadoop/tmp022
          - name: logs
            hostPath:
              path: /home/data/bjrddata/hadoop/logs022

    重新部署集群:(可以看到Cluster ip已经没有了)


    wordcount运行结果:

    root@hdp-5-svc:/hadoop-2.7.3# hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount hdfs://hdp-1-svc:9000/test/NOTICE.txt hdfs://hdp-1-svc:9000/test/output01
    17/07/03 09:53:57 INFO client.RMProxy: Connecting to ResourceManager at hdp-1-svc/192.168.25.14:8032
    17/07/03 09:53:57 INFO input.FileInputFormat: Total input paths to process : 1
    17/07/03 09:53:57 INFO mapreduce.JobSubmitter: number of splits:1
    17/07/03 09:53:58 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1499075310680_0001
    17/07/03 09:53:58 INFO impl.YarnClientImpl: Submitted application application_1499075310680_0001
    17/07/03 09:53:58 INFO mapreduce.Job: The url to track the job: http://hdp-1-svc:8088/proxy/application_1499075310680_0001/
    17/07/03 09:53:58 INFO mapreduce.Job: Running job: job_1499075310680_0001
    17/07/03 09:54:04 INFO mapreduce.Job: Job job_1499075310680_0001 running in uber mode : false
    17/07/03 09:54:04 INFO mapreduce.Job:  map 0% reduce 0%
    17/07/03 09:54:09 INFO mapreduce.Job:  map 100% reduce 0%
    17/07/03 09:54:14 INFO mapreduce.Job:  map 100% reduce 100%
    17/07/03 09:54:15 INFO mapreduce.Job: Job job_1499075310680_0001 completed successfully
    17/07/03 09:54:15 INFO mapreduce.Job: Counters: 49
        File System Counters
            FILE: Number of bytes read=11392
            FILE: Number of bytes written=261045
            FILE: Number of read operations=0
            FILE: Number of large read operations=0
            FILE: Number of write operations=0
            HDFS: Number of bytes read=15080
            HDFS: Number of bytes written=8969
            HDFS: Number of read operations=6
            HDFS: Number of large read operations=0
            HDFS: Number of write operations=2
        Job Counters
            Launched map tasks=1
            Launched reduce tasks=1
            Data-local map tasks=1
            Total time spent by all maps in occupied slots (ms)=2404
            Total time spent by all reduces in occupied slots (ms)=2690
            Total time spent by all map tasks (ms)=2404
            Total time spent by all reduce tasks (ms)=2690
            Total vcore-milliseconds taken by all map tasks=2404
            Total vcore-milliseconds taken by all reduce tasks=2690
            Total megabyte-milliseconds taken by all map tasks=2461696
            Total megabyte-milliseconds taken by all reduce tasks=2754560
        Map-Reduce Framework
            Map input records=437
            Map output records=1682
            Map output bytes=20803
            Map output materialized bytes=11392
            Input split bytes=102
            Combine input records=1682
            Combine output records=614
            Reduce input groups=614
            Reduce shuffle bytes=11392
            Reduce input records=614
            Reduce output records=614
            Spilled Records=1228
            Shuffled Maps =1
            Failed Shuffles=0
            Merged Map outputs=1
            GC time elapsed (ms)=173
            CPU time spent (ms)=1800
            Physical memory (bytes) snapshot=470913024
            Virtual memory (bytes) snapshot=4067495936
            Total committed heap usage (bytes)=342360064
        Shuffle Errors
            BAD_ID=0
            CONNECTION=0
            IO_ERROR=0
            WRONG_LENGTH=0
            WRONG_MAP=0
            WRONG_REDUCE=0
        File Input Format Counters
            Bytes Read=14978
        File Output Format Counters

    执行成功


    作者:俺是亮哥
    链接:http://www.jianshu.com/p/38606bbe138b
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    展开全文
  • 目前的大数据平台存在的问题: 通过手工方式直接部署在物理机上,过程复杂、效率低,不适合大规模集群部署和动态扩容。 由于平台组件繁多,对宿主机底层库依赖过高,一旦安装完成,很难进行迁移,也无法做成模版...

    目前的大数据平台存在的问题:

    • 通过手工方式直接部署在物理机上,过程复杂、效率低,不适合大规模集群的部署和动态扩容。
    • 由于平台组件繁多,对宿主机底层库依赖过高,一旦安装完成,很难进行迁移,也无法做成模版进行重复使用。
    • 组件升级不够灵活,往往会对有相同底层依赖的其他组件带来影响。
    • 采用虚机部署时,会对宿主机产生资源浪费、开销大。
    • 物理机或虚机关启等管理操作速度较慢。
    • 无法在同一套物理集群上部署多套大数据平台,使用虚机的方案太耗费资源。

    针对上述问题,我们打算用时下流行的Docker容器来封装大数据各个组件,用Google的神器Kubernetes来编排这些Docker容器,最终达到:

    • 平台能够自动化的快速部署(小规模集群能够达到秒级)、动态扩容。
    • 平台构建一次,就能够形成模版重复使用、灵活迁移。
    • 平台构建一次,就能够灵活部署在不同的环境中(比如公有云、私有云、裸机,虚拟机)。
    • 组件能够灵活升级、灵活替代。
    • 消除线上线下环境不一致导致的问题,再也不会有“在我的机器上运行的好好的”这种托词。
    • 因为其多资源的低消耗,在物理集群上能同时部署多套大数据平台,供不同部门独 享。
    • 很适合持续集成/持续部署(CI/CD)的环境,因为可以自动的下载、绿色的安装和彻底清除应用程序,不会影响宿主机的环境。

    本篇是该系列的第一篇,手把手教你通过K8s部署zookeeper集群,涉及到的概念,各位看官自行脑补,我只讲一下部署过程,直接上干货了。

    - 使用Kargo搭建Kubernetes 1.6集群:

    地址角色
    10.0.7.14Ansible Client (Kargo用到的工具)
    10.0.8.182Master, NODE 1
    10.0.8.183NODE 2

    [下文提到的kargo.tg、kargo_images_v1.6.1.tar.gz压缩包]http://pan.baidu.com/s/1kUKyfBL

    1,我用笔记本(macOS系统),作为Ansible client。先新建一个文件夹kargo,把kargo.tgz放进去并解压,目录结构如下:

    2,需要安装python 2.7、pip 9.0.1、python-netaddr、ansible 2.3.1.0等工具 [ansible安装]http://valdhaus.co/writings/ansible-mac-osx/

    3,修改 inventory/inventory.cfg

    wangliangdeMacBook-Pro:kargo wangliang$ pwd
    /Users/wangliang/kargo/kargo
    wangliangdeMacBook-Pro:kargo wangliang$ vim inventory/inventory.cfg
    
    [all]
    node1    ansible_user=app ansible_host=10.0.8.182  ip=10.0.8.182 access_ip=10.0.8.182
    node2    ansible_user=app ansible_host=10.0.8.183  ip=10.0.8.183 access_ip=10.0.8.183
    
    [kube-master]
    node1    ip=10.0.8.182 access_ip=10.0.8.182
    
    [kube-node]
    node1
    node2
    
    [etcd]
    node1
    
    [k8s-cluster:children]
    kube-node
    kube-master
    
    [calico-rr]

    4,分别在10.0.8.182(Node 1)、10.0.8.183(Node 2)上做如下操作:
    首先安装Docker 1.13.1,并启动服务
    [Ubuntu安装Docker]http://www.linuxidc.com/Linux/2017-01/139985.htm

    其次把kargo_images_v1.6.1.tar.gz 拷贝到要安装k8s的节点上,放到k8s文件夹内,并解压,目录结构如下:




    5,在kargo_images_v1.6.1目录下,进入bash,执行:

    ➜  k8s cd kargo_images_v1.6.1
    ➜  kargo_images_v1.6.1 pwd
    /data/k8s/kargo_images_v1.6.1
    ➜  kargo_images_v1.6.1 bash
    app@yuyan1:/data/k8s/kargo_images_v1.6.1$images=$(ls -l ../kargo_images_v1.6.1|awk -F' ' '{ print $9 }')
    
    app@yuyan1:/data/k8s/kargo_images_v1.6.1$ for x in ${images[*]}; do sudo docker load -i $x; done

    将目录下的镜像放入docker images。


    6, Node1、Node2和Mac间都要SSH免密,Mac上还要打开共享里面的允许远端访问



    Node1、Node2、Mac都在用户目录下执行

    ➜  ~ cd /home/app
    ssh-keygen -t rsa  #一路回车就行
    Generating public/private rsa key pair.
    Enter file in which to save the key (/home/app/.ssh/id_rsa):
    Created directory '/home/app/.ssh'.
    Enter passphrase (empty for no passphrase):
    Enter same passphrase again:
    Your identification has been saved in /home/app/.ssh/id_rsa.
    Your public key has been saved in /home/app/.ssh/id_rsa.pub.
    The key fingerprint is:
    7c:f4:2f:21:f2:85:7f:20:38:02:1d:ef:79:39:b6:be root@dcos1
    The key's randomart image is:
    +--[ RSA 2048]----+
    |      .          |
    |     . o         |
    |    . . . .      |
    |     . o + +     |
    |      . S X =    |
    |       . B B +   |
    |          o o o  |
    |         .   o   |
    |          E.     |
    +-----------------+
    
    ➜  ~ cd /home/app/.ssh
    ➜  .ssh ssh-copy-id Node2
    ➜  .ssh ssh-copy-id Mac
    
    每次执行,步骤都如下类似:
    The authenticity of host 'Node1 (10.0.8.183)' can't be established.
    ECDSA key fingerprint is 91:1a:13:a8:57:2b:a0:42:4d:aa:c9:83:c3:33:16:f9.
    Are you sure you want to continue connecting (yes/no)? yes
    /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
    /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
    root@dcos1's password:
    
    Number of key(s) added: 1
    
    Now try logging into the machine, with:   "ssh 'Node2'"
    and check to make sure that only the key(s) you wanted were added.

    所有虚机都执行完成后,可以通过ssh hostname来查看之间是否ssh连接已经免密了,如下测试

    ➜  ~ ssh 10.0.8.183
    Welcome to Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-62-generic x86_64)
    
     * Documentation:  https://help.ubuntu.com
     * Management:     https://landscape.canonical.com
     * Support:        https://ubuntu.com/advantage
    
    180 packages can be updated.
    75 updates are security updates.
    
    
    Last login: Wed Jun 28 09:16:54 2017 from 10.0.7.14
    ➜  ~

    7,在Ansible client(Mac)上执行

    $ ansible-playbook -i ~/kargo/inventory/inventory.cfg cluster.yml -b -v --user=username --ask-sudo-pass

    安装成功,在Mac上可以看到如下输出:


    在Node 1上可以看到:


    遇到的错误:
    1,有如下错误:

    kubectl The connection to the server localhost:8080 was refused

    修改了vim inventory/group_vars/k8s-cluster.ym 里面的8080为28080,避免和别人冲突,又有如下错误:

    kubernetes/master : Master | wait for the apiserver to be running

    原因是apiserver的镜像起不了,无法提供服务
    怀疑可能是不支持docker 1.17版本,所以更换为docker 1.13.1版本子再次安装后没有上述错误了,安装成功。切记,要用docker 1.13.1版本。

    2,如果按照上述操作始终没有成功,可以把节点上的

    /run/kubernetes
    /etc/kubernetes

    都删除,然后把docker也都卸载重新装。然后在Ansible client节点上重新部署就可以啦。

    • 使用Dockerfile制作包含zkui 2.0 的Zookeeper 3.4.10版本的镜像:
      1,建立你要做docker的目录,结构如下:

    2,其中Dockerfile如下:

    FROM openjdk:8-jre-alpine
    MAINTAINER Wang Liang <wangl8@knownsec.com>
    
    # Install required packages
    RUN apk add --no-cache \
        bash \
        su-exec
    
    ENV ZOO_USER=zookeeper \
        ZOO_CONF_DIR=/conf \
        ZOO_DATA_DIR=/data \
        ZOO_UI_DIR=/zkui \
        ZOO_DATA_LOG_DIR=/datalog \
        ZOO_PORT=2181 \
        ZOO_TICK_TIME=2000 \
        ZOO_INIT_LIMIT=5 \
        ZOO_SYNC_LIMIT=2
    
    # Add a user and make dirs
    RUN set -x \
        && adduser -D "$ZOO_USER" \
        && mkdir -p "$ZOO_DATA_LOG_DIR" "$ZOO_DATA_DIR" "$ZOO_CONF_DIR" \
        && chown "$ZOO_USER:$ZOO_USER" "$ZOO_DATA_LOG_DIR" "$ZOO_DATA_DIR" "$ZOO_CONF_DIR"
    
    ARG GPG_KEY=C823E3E5B12AF29C67F81976F5CECB3CB5E9BD2D
    ARG DISTRO_NAME=zookeeper-3.4.10
    
    # Download Apache Zookeeper, verify its PGP signature, untar and clean up
    RUN set -x \
        && apk add --no-cache --virtual .build-deps \
            gnupg \
        && wget -q "http://www.apache.org/dist/zookeeper/$DISTRO_NAME/$DISTRO_NAME.tar.gz" \
        && wget -q "http://www.apache.org/dist/zookeeper/$DISTRO_NAME/$DISTRO_NAME.tar.gz.asc" \
        && export GNUPGHOME="$(mktemp -d)" \
        && gpg --keyserver ha.pool.sks-keyservers.net --recv-key "$GPG_KEY" \
        && gpg --batch --verify "$DISTRO_NAME.tar.gz.asc" "$DISTRO_NAME.tar.gz" \
        && tar -xzf "$DISTRO_NAME.tar.gz" \
        && mv "$DISTRO_NAME/conf/"* "$ZOO_CONF_DIR" \
        && rm -r "$GNUPGHOME" "$DISTRO_NAME.tar.gz" "$DISTRO_NAME.tar.gz.asc" \
        && apk del .build-deps
    
    ADD zkui-master $ZOO_UI_DIR
    
    WORKDIR $DISTRO_NAME
    VOLUME ["$ZOO_DATA_DIR", "$ZOO_DATA_LOG_DIR"]
    
    EXPOSE $ZOO_PORT 2888 3888
    
    ENV PATH=$PATH:/$DISTRO_NAME/bin:$ZOO_UI_DIR \
        ZOOCFGDIR=$ZOO_CONF_DIR
    
    COPY docker-entrypoint.sh /
    ENTRYPOINT ["/docker-entrypoint.sh"]

    3,docker-entrypoint.sh如下:

    #!/bin/bash
    
    set -e
    
    # Allow the container to be started with `--user`
    if [ "$1" = 'zkServer.sh' -a "$(id -u)" = '0' ]; then
        chown -R "$ZOO_USER" "$ZOO_DATA_DIR" "$ZOO_DATA_LOG_DIR"
        exec su-exec "$ZOO_USER" "$0" "$@"
    fi
    
    # Generate the config only if it doesn't exist
    if [ ! -f "$ZOO_CONF_DIR/zoo.cfg" ]; then
        CONFIG="$ZOO_CONF_DIR/zoo.cfg"
    
        echo "clientPort=$ZOO_PORT" >> "$CONFIG"
        echo "dataDir=$ZOO_DATA_DIR" >> "$CONFIG"
        echo "dataLogDir=$ZOO_DATA_LOG_DIR" >> "$CONFIG"
    
        echo "tickTime=$ZOO_TICK_TIME" >> "$CONFIG"
        echo "initLimit=$ZOO_INIT_LIMIT" >> "$CONFIG"
        echo "syncLimit=$ZOO_SYNC_LIMIT" >> "$CONFIG"
    
        for server in $ZOO_SERVERS; do
            echo "$server" >> "$CONFIG"
        done
    fi
    
    if [ -f "$ZOO_UI_DIR/config.cfg" ]; then
        CONFIG="$ZOO_UI_DIR/config.cfg"
    
        echo "serverPort=$ZOO_UI_PORT" >> "$CONFIG"
        echo "zkServer=$ZOO_UI_SERVER" >> "$CONFIG"
    fi
    
    # Write myid only if it doesn't exist
    if [ ! -f "$ZOO_DATA_DIR/myid" ]; then
        echo "${ZOO_MY_ID:-1}" > "$ZOO_DATA_DIR/myid"
    fi
    
    cd $ZOO_UI_DIR
    exec nohup java -jar zkui-2.0-SNAPSHOT-jar-with-dependencies.jar &
    exec zkServer.sh start-foreground

    [制作过程需要的文件]http://pan.baidu.com/s/1i5IG6sH

    执行

    ➜  wldocker sudo docker build -t zookeeper_3.4.10_zkui_2.0:0.0.1 .

    就可以制作出包含ZKUI的zookeeper 3.4.10的docker镜像了


    把该镜像上传到HARBOR库,稍后k8s编排时会用到。

    • 通过Kubernetes 编排启动Zookeeper集群:
      我们采取的方案是每个zkserver属于一个pod,每个pod绑定一个物理主机。
      只需要完成yaml文件即可:

    zk-1.yaml:

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: zk-1-svc
      labels:
        app: zk-1-svc
    spec:
      ports:
      - port: 2888
        name: server
      - port: 3888
        name: leader-election
      - port: 2181
        name: client
      - port: 9999
        name: zkui
      selector:
        app: zk-1
      type: NodePort
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: zk-1-cm
    data:
      jvm.heap: "1G"
      tick: "2000"
      init: "10"
      sync: "5"
      client.cnxns: "60"
      snap.retain: "3"
      purge.interval: "0"
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: zk-1
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: zk-1
        spec:
          nodeSelector:
            zk: zk-1
          containers:
          - name: myzk
            imagePullPolicy: IfNotPresent
            image: registry.k8s.intra.knownsec.com/bigdata/zookeeper_3.4.10_zkui_2.0:0.0.1
            resources:
              requests:
                memory: "2Gi"
                cpu: "500m"
            ports:
            - containerPort: 2181
              name: client
            - containerPort: 2888
              name: server
            - containerPort: 3888
              name: leader-election
            - containerPort: 9999
              name: zkui
            env:
            - name : ZK_HEAP_SIZE
              valueFrom:
                configMapKeyRef:
                    name: zk-1-cm
                    key: jvm.heap
            - name : ZK_TICK_TIME
              valueFrom:
                configMapKeyRef:
                    name: zk-1-cm
                    key: tick
            - name : ZK_INIT_LIMIT
              valueFrom:
                configMapKeyRef:
                    name: zk-1-cm
                    key: init
            - name : ZK_SYNC_LIMIT
              valueFrom:
                configMapKeyRef:
                    name: zk-1-cm
                    key: tick
            - name : ZK_MAX_CLIENT_CNXNS
              valueFrom:
                configMapKeyRef:
                    name: zk-1-cm
                    key: client.cnxns
            - name: ZK_SNAP_RETAIN_COUNT
              valueFrom:
                configMapKeyRef:
                    name: zk-1-cm
                    key: snap.retain
            - name: ZK_PURGE_INTERVAL
              valueFrom:
                configMapKeyRef:
                    name: zk-1-cm
                    key: purge.interval
            - name: ZK_CLIENT_PORT
              value: "2181"
            - name: ZK_SERVER_PORT
              value: "2888"
            - name: ZK_ELECTION_PORT
              value: "3888"
            - name: ZOO_MY_ID
              value: "1"
            - name: ZOO_SERVERS
              value: "server.1=0.0.0.0:2888:3888 server.2=zk-2-svc:2888:3888"
            - name: ZOO_UI_PORT
              value: "9999"
            - name: ZOO_UI_SERVER
              value: "zk-1-svc:2181,zk-2-svc:2181"
    #        readinessProbe:
    #          exec:
    #            command:
    #            - "zkok.sh"
    #          initialDelaySeconds: 10
    #          timeoutSeconds: 5
    #        livenessProbe:
    #          exec:
    #            command:
    #            - "zkok.sh"
    #          initialDelaySeconds: 10
    #          timeoutSeconds: 5
            volumeMounts:
            - name: data
              mountPath: /data
            - name: datalog
              mountPath: /datalog
          volumes:
          - name: data
            hostPath:
              path: /data/k8s/zookeeper/data
          - name: datalog
            hostPath:
              path: /data/k8s/zookeeper/datalog

    zk-2.yaml:

    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: zk-2-svc
      labels:
        app: zk-2-svc
    spec:
      ports:
      - port: 2888
        name: server
      - port: 3888
        name: leader-election
      - port: 2181
        name: client
      - port: 9999
        name: zkui
      selector:
        app: zk-2
      type: NodePort
    ---
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: zk-2-cm
    data:
      jvm.heap: "1G"
      tick: "2000"
      init: "10"
      sync: "5"
      client.cnxns: "60"
      snap.retain: "3"
      purge.interval: "0"
    ---
    apiVersion: extensions/v1beta1
    kind: Deployment
    metadata:
      name: zk-2
    spec:
      replicas: 1
      template:
        metadata:
          labels:
            app: zk-2
        spec:
          nodeSelector:
            zk: zk-2
          containers:
          - name: myzk
            imagePullPolicy: IfNotPresent
            image: registry.k8s.intra.knownsec.com/bigdata/zookeeper_3.4.10_zkui_2.0:0.0.1
            resources:
              requests:
                memory: "2Gi"
                cpu: "500m"
            ports:
            - containerPort: 2181
              name: client
            - containerPort: 2888
              name: server
            - containerPort: 3888
              name: leader-election
            - containerPort: 9999
              name: zkui
            env:
            - name : ZK_HEAP_SIZE
              valueFrom:
                configMapKeyRef:
                    name: zk-2-cm
                    key: jvm.heap
            - name : ZK_TICK_TIME
              valueFrom:
                configMapKeyRef:
                    name: zk-2-cm
                    key: tick
            - name : ZK_INIT_LIMIT
              valueFrom:
                configMapKeyRef:
                    name: zk-2-cm
                    key: init
            - name : ZK_SYNC_LIMIT
              valueFrom:
                configMapKeyRef:
                    name: zk-2-cm
                    key: tick
            - name : ZK_MAX_CLIENT_CNXNS
              valueFrom:
                configMapKeyRef:
                    name: zk-2-cm
                    key: client.cnxns
            - name: ZK_SNAP_RETAIN_COUNT
              valueFrom:
                configMapKeyRef:
                    name: zk-2-cm
                    key: snap.retain
            - name: ZK_PURGE_INTERVAL
              valueFrom:
                configMapKeyRef:
                    name: zk-2-cm
                    key: purge.interval
            - name: ZK_CLIENT_PORT
              value: "2181"
            - name: ZK_SERVER_PORT
              value: "2888"
            - name: ZK_ELECTION_PORT
              value: "3888"
            - name: ZOO_MY_ID
              value: "2"
            - name: ZOO_SERVERS
              value: "server.1=zk-1-svc:2888:3888 server.2=0.0.0.0:2888:3888 "
            - name: ZOO_UI_PORT
              value: "9999"
            - name: ZOO_UI_SERVER
              value: "zk-1-svc:2181,zk-2-svc:2181"
    #        readinessProbe:
    #          exec:
    #            command:
    #            - "zkok.sh"
    #          initialDelaySeconds: 10
    #          timeoutSeconds: 5
    #        livenessProbe:
    #          exec:
    #            command:
    #            - "zkok.sh"
    #          initialDelaySeconds: 10
    #          timeoutSeconds: 5
            volumeMounts:
            - name: data
              mountPath: /data
            - name: datalog
              mountPath: /datalog
          volumes:
          - name: data
            hostPath:
              path: /data/k8s/zookeeper/data
          - name: datalog
            hostPath:
              path: /data/k8s/zookeeper/datalog

    [yaml共享]http://pan.baidu.com/s/1jIyvGPK

    执行:

    ➜  zookeeper kubectl create -f zk-1.yaml
    service "zk-1-svc" created
    configmap "zk-1-cm" created
    deployment "zk-1" created
    ➜  zookeeper kubectl create -f zk-2.yaml
    service "zk-2-svc" created
    configmap "zk-2-cm" created
    deployment "zk-2" created
    • 功能验证:
    ➜  zookeeper kubectl get po  #看po情况
    NAME                    READY     STATUS    RESTARTS   AGE
    zk-1-1238243890-phcm8   1/1       Running   0          1m
    zk-2-4022999611-x27vq   1/1       Running   0          1m
    ➜  zookeeper kubectl get po -o wide #看绑定物理节点情况
    NAME                    READY     STATUS    RESTARTS   AGE       IP               NODE
    zk-1-1238243890-phcm8   1/1       Running   0          1m        11.233.112.152   yuyan1
    zk-2-4022999611-x27vq   1/1       Running   0          1m        11.233.77.83     yuyan2
    ➜  zookeeper kubectl get service  #看端口映射情况
    NAME         CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                       AGE
    kubernetes   11.233.0.1      <none>        443/TCP                                                       4d
    zk-1-svc     11.233.30.168   <nodes>       2888:31292/TCP,3888:30513/TCP,2181:31570/TCP,9999:30476/TCP   1m
    zk-2-svc     11.233.27.68    <nodes>       2888:30906/TCP,3888:30842/TCP,2181:32473/TCP,9999:31490/TCP   1m
    ➜  zookeeper kubectl exec  zk-2-4022999611-x27vq -t -i -- bash #进入容器看服务情况
    bash-4.3# zkServer.sh status
    ZooKeeper JMX enabled by default
    Using config: /conf/zoo.cfg
    Mode: leader  #选举正常

    通过宿主机ip加映射后的端口访问zkui http://10.0.8.183:31490


    提供对外访问正常

    参考
    [Kargo部署K8s]http://oo3p.com/2017/04/17/kargo容器化部署kubernetes高可用集群/
    [zookeeper docker]https://github.com/31z4/zookeeper-docker/tree/f12428ab7c6ea263ef037cf258129b83276c009c
    [k8s pod]https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
    [k8s编排zookeeper集群]https://github.com/kubernetes/contrib/tree/master/statefulsets/zookeeper



    作者:俺是亮哥
    链接:http://www.jianshu.com/p/315e18c2f3a2
    來源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
    展开全文
  • Ambari快速部署Hadoop大数据环境

    万次阅读 2017-02-27 11:40:16
    Ambari 是什么 Ambari 跟 Hadoop 等开源软件一样,也是 Apache Software Foundation 中的一个项目,并且是顶级项目。

    Ambari 是什么

    Ambari 跟 Hadoop 等开源软件一样,也是 Apache Software Foundation 中的一个项目,并且是顶级项目。就 Ambari 的作用来说,就是创建、管理、监视 Hadoop 的集群,但是这里的 Hadoop 是广义,指的是 Hadoop 整个生态圈(例如 Hive,Hbase,Sqoop,Zookeeper 等),而并不仅是特指 Hadoop。用一句话来说,Ambari 就是为了让 Hadoop 以及相关的大数据软件更容易使用的一个工具。
    说到这里,大家就应该明白什么人最需要 Ambari 了。那些苦苦花费好几天去安装、调试 Hadoop 的初学者是最能体会到 Ambari 的方便之处的。而且,Ambari 现在所支持的平台组件也越来越多,例如流行的 Spark,Storm 等计算框架,以及资源调度平台 YARN 等,我们都能轻松地通过 Ambari 来进行部署。
    Ambari 自身也是一个分布式架构的软件,主要由两部分组成:Ambari Server 和 Ambari Agent。简单来说,用户通过 Ambari Server 通知 Ambari Agent 安装对应的软件;Agent 会定时地发送各个机器每个软件模块的状态给 Ambari Server,最终这些状态信息会呈现在 Ambari 的 GUI,方便用户了解到集群的各种状态,并进行相应的维护。

    Ambari 的安装

    Ambari安装准备

    关于 Ambari 的安装,目前网上能找到两个发行版,一个是 Apache 的 Ambari,另一个是 Hortonworks 的,两者区别不大。这里就以 Apache 的 Ambari 2.1.2 作为示例。本文使用四台 centos 6.8 作为安装环境,三台机器分别为Ambari.domain、NameNode.domain、Hadoop01.domain、Hadoop02.domain。Ambari计划安装为 Ambari 的 Server,NameNode为管理节点,另外两台为 Ambari Agent。
    安装 Ambari 最方便的方式就是使用公共的库源(public repository)。[搭建本地库(local repository)见Ambari-server私有yum源搭建及设置]。这个不是本文重点,所以不在此赘述。在进行具体的安装之前,需要做几个准备工作。
    SSH 的无密码登录(见配置Ambari-server到agent单向的免密码登陆);
    Ambari 的 Server 会 SSH 到 Agent 的机器,拷贝并执行一些命令。因此我们需要配置 Ambari Server 到 Agent 的 SSH 无密码登录。在这个例子里,Ambari可以 SSH 无密码登录另外三台机器。
    确保 Yum 可以正常工作;
    通过公共库(public repository),安装 Hadoop 这些软件,背后其实就是应用 Yum 在安装公共库里面的 rpm 包。所以这里需要您的机器都能访问 Internet。
    确保 home 目录的写权限,Ambari 会创建一些 OS 用户。
    确保机器的 Python 版本大于或等于 2.6(系统默认就是 2.6 的)。
    以上的准备工作完成后,便可以真正的开始安装 Ambari 了。

    Ambari安装过程

    首先需要获取 Ambari 的公共库文件(public repository)。登录到 Linux 主机并执行下面的命令(也可以自己手工下载):
    wget http://public-repo-1.hortonworks.com/ambari/centos6/2.x/updates/2.1.2/ambari.repo
    将下载的 ambari.repo 文件拷贝到 Linux 的系统目录/etc/yum.repos.d/。拷贝完后,我们需要获取该公共库的所有的源文件列表。依次执行以下命令。
    #yum clean all
    #yum list|grep ambari
    ambari-repo
    如果可以看到 Ambari 的对应版本的安装包列表,说明公共库已配置成功。然后就可以安装 Ambari 的 package 了。执行下面的命令安装 Ambari Server 到该机器。
    #yum install ambari-server
    待安装完成后,便需要对 Ambari Server 做一个简单的配置。执行下面的命令。
    #amari-server setup
    在这个交互式的设置中,采用默认配置即可。Ambari 会使用 Postgres 数据库,默认会安装并使用 Oracle 的 JDK。默认设置了 Ambari GUI 的登录用户为 admin/admin。并且指定 Ambari Server 的运行用户为 root。
    简单的 setup 配置完成后。就可以启动 Ambari 了。运行下面的命令。
    #ambari-server start
    当成功启动 Ambari Server 之后,便可以从浏览器登录,默认的端口为 8080。以本文环境为例,在浏览器的地址栏输入 http://ambari.domain:8080,登录密码为 admin/admin。登入 Ambari 之后的页面如下图。
    Ambari 的 welcome 页面
    至此,Ambari Server 就安装完成了。

    部署一个 Hadoop2.x 集群

    到这一节,我们将可以真正地体验到 Ambari 的用武之地,以及它所能带来的方便之处。
    登录 Ambari 之后,点击按钮“Launch Install Wizard”,就可以开始创建属于自己的大数据平台。
    首先命名集群的名字。本环境为 BigData。
    接下来,选择一个 Stack,这个 Stack 相当于一个 Hadoop 生态圈软件的集合。Stack 的版本越高,里面的软件版本也就越高。这里我们选择 HDP2.3,里面的对应的 Hadoop 版本为 2.7.x。
    接下来,指定 Agent 机器(如果配置了域,必须包含完整域名),这些机器会被安装 Hadoop 等软件包。咱们这里选择“Perform manual registration on hosts and do not use SSH“。 三台机器都要手动安装 Ambari Agent。具体参见下图示例。
    install options
    [root@namenode ~]# yum install -y ambari-agent
    [root@namenode ~]# vi /etc/ambari-agent/conf/ambari-agent.ini
    修改其中的hostname为Ambari即可
    [root@namenode ~]# /etc/init.d/ambari-agent start
    [root@NameNode ~]# /etc/init.d/ambari-agent status
    手动安装agent
    Hadoop01、Hadoop02安装方式同上。
    客户端手动注册
    点击”Register and Confirm”后系统自动开始注册主机和配置主机
    注册主机

    Hadoop集群组件选择与安装

    一般根据业务选择安装的服务
    choose service

    master服务节点选择

    选择各组件master服务安装在哪些节点(注意:服务分为master/salves,多个master不推荐安装在同一个主机上面)
    master

    slaves服务节点选择

    选择slaves服务的安装节点,节点客户端安装
    推荐DataNode、RegionServe、client组件都安装
    client

    自定义服务配置

    (1)、hdfs目录配置:
    注意检查目录空间大小,尽量放置在大的目录下
    (2)、hive服务配置与检测
    hvie配置
    配置结束后Ambari 会总结一个安装列表,供用户审阅。这里没问题,就直接下一步。
    Ambari 会开始安装选择的 Service 到 Ambari Agent 的机器(如下图)。这里可能需要等好一会。安装完成之后,Ambari 就会启动这些 Service。
    安装进度

    安装完成

    安装完成之后,就可以查看 Ambari 的 Dashboard 了。
    Dashboard
    至此,您专属的 bigdata 集群已经安装完成。

    展开全文
  • 企业大数据上云的安全顾虑 企业大数据在上云过程中,通常会有这样一些安全顾虑:“数据从企业内部迁移到云上后,数据有没有可能会被丢掉? ”,“数据在云上存储时,数据是否可能被篡改?”, “数据在云上使用的时候,...
  • K8S集群搭建.zip

    2020-07-26 23:30:12
    Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。
  • 本来想使用自建的K8S集群来演示混合部署的,无奈作者的电脑配置实在是跟不上,一开虚拟机就卡得不行。于是果断选择氪金使用阿里云的容器服务K8S版,既省去了自己各种操作的压力,也权当是体验一把国内顶级的...
  • 想要系统学习k8s的可以关注下本人首页的套餐课程 1. 学习使用Jenkins自动构建 2. 学习Jenkins使用k8s执行构建3. 学习Jenkins BlueOcean使用4. 学习Jenkins声明式流水线的设计5. 学习Jenkins账号管理 6. 学习...
  • k8s docker集群搭建

    2019-08-20 18:01:04
    k8s docker集群搭建 2017年12月05日 13:09:39阅读数:43329 个人分类:Kubernetes yaml Etcd 一、Kubernetes系列之介绍篇 •Kubernetes介绍 1.背景介绍  云计算飞速发展  - IaaS  ...
  • 基于Kubernetes的Spark集群部署实践

    千次阅读 2017-11-15 21:22:11
    Spark是新一代分布式内存计算框架,Apache开源的顶级项目。相比于Hadoop Map-Reduce计算框架,Spark将中间计算结果保留在内存中,速度提升10~100倍;同时它还提供更丰富的算子,采用弹性分布式数据集(RDD)实现迭代...
  • k8s总结感悟

    千次阅读 2018-07-16 09:49:53
     事件描述:公司准备将公司产品上云统一管理,所以需要搭建云平台,所以下派任务,使用当下最火的K8S(一切开源为主)进行搭建;事件经历时间:半年左右事件过程:1.k8s的基础就是镜像,Docker学习也有半个月时间,...
  • Kubernetes之所以被叫做k8s,业界有两种说法,通俗的说法是k和s之间有8个字母,另一种比较说法是k8s集群至少需要搭建8遍才能搭建成功。当然,在实际使用时,可能不止8遍。k8s的诞生,把运维从传统转变到了DevOps...
  • k8s的持续发布

    2020-06-16 09:11:09
    本课程主要包含k8s集群的安装,k8s各 种资源详细介绍和使用,k8s各种扩展组件的部署和使用,k8s核心功能弹性伸缩演示,k8s持久化存储,k8s代码自动发布,让你真正的能够让你的业务在k8s中落地运行!
  • Docker集群管理三剑客

    万人学习 2019-06-24 13:05:02
    Docker Machine为本地,私有数据中心及公有云平台提供Docker引擎,实现从零到Docker的一键部署。 Docker Compose是一个编排多容器分布式部署的工具,提供命令集管理容器化应用的完整开发周期,包括服务构建,启动和...
  • 在 12 月 22 日 ECUG 的下午场 ,七牛云容器计算部技术总监袁晓沛为大家带来了主题为《基于 K8S 的 DCOS 之路》的精彩分享,向大家介绍了七牛容器云目前 K8S 的状况和产品思考。同时,他在会上讲述了如何通过七牛...
  • 想要系统学习k8s的可以关注下本人首页的课程 1、课程亮点         1、课程基于世界500强使用经验定制开发,覆盖常用的k8s知识;    ...
1 2 3 4 5 ... 13
收藏数 259
精华内容 103
关键字:

k8s一键部署搭建大数据集群