21-第20课:K8S+Docker 部署 Spring Cloud 集群

  1. 集群环境搭建
  2. 创建 Docker 镜像
  3. 系统发布

在一个实际的大型系统中,微服务架构可能由成百上千个服务组成,我们发布一个系统如果都单纯的通过打包上传,再发布,工作量无疑是巨大的,也是不可取的,前面我们知道了可以通过 Jenkins 帮我们自动化完成发布任务。

但是,我们知道一个 Java 应用其实是比较占用资源的,每个服务都发布到物理宿主机上面,资源开销也是巨大的,而且每扩展一台服务器,都需要重复部署相同的软件,这种方式显然是不可取的。

容器技术的出现带给了我们新的思路,我们将服务打包成镜像,放到容器中,通过容器来运行我们的服务,这样我们可以很方便进行分布式的管理,同样的服务也可以很方便进行水平扩展。

Docker 是容器技术方便的佼佼者,它是一个开源容器。而 Kubernetes(以下简称 K8S),是一个分布式集群方案的平台,它天生就是和 Docker 一对,通过 K8S 和 Docker 的配合,我们很容易搭建分布式集群环境。

下面,我们就来看看 K8S 和 Docker 的吸引之处。

集群环境搭建

本文用一台虚拟机模拟集群环境。

操作系统:CentOS7 64位

配置:内存2GB,硬盘40GB。

注:真正的分布式环境搭建方案类似,可以参考博文:《Kubernetes学习2——集群部署与搭建》

下面开始搭建集群环境。

  1. 关闭防火墙:

    systemctl disable firewalld
    systemctl stop firewalld
    iptables -P FORWARD ACCEPT
  2. 安装 etcd:

    yum install etcd -y

    安装完成后启动 etcd:

    systemctl enable etcd
    systemctl start etcd

    启动后,我们可以检查 etcd 健康状况:

    etcdctl -C http://localhost:2379 cluster-health

    出现下面信息说明 etcd 目前是稳定的:

    member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379
    cluster is healthy
  3. 安装 Docker:

    yum install docker -y

    完成后启动 Docker:

    chkconfig docker on
    systemctl start docker
  4. 安装 Kubernetes:

    yum install kubernetes -y

    安装完成后修改配置文件 /etc/kubernetes/apiserver

    vim /etc/kubernetes/apiserver

    KUBE_ADMISSION_CONTROL 后面的 ServiceAccount 删掉,如:

    KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"

    然后依次启动 kubernetes-server

    systemctl enable kube-apiserver
    systemctl start kube-apiserver
    systemctl enable kube-controller-manager
    systemctl start kube-controller-manager
    systemctl enable kube-scheduler
    systemctl start kube-scheduler

    再依次启动 kubernetes-client

    systemctl enable kubelet
    systemctl start kubelet
    systemctl enable kube-proxy
    systemctl start kube-proxy

    我们查看集群状态:

    kubectl get no

    可以看到以下信息:

    NAME        STATUS    AGE
    127.0.0.1   Ready     1h

    至此,我们基于 K8S 的集群环境就搭建完成了,但是我们发布到 Docker 去外部是无法访问的,还要安装 Flannel 以覆盖网络。

  5. 安装 Flannel:

    yum install flannel -y

    安装完成后修改配置文件:

    vim /etc/sysconfig/flanneld

    内容如下:

    # Flanneld configuration options  
    
    # etcd url location.  Point this to the server where etcd runs
    FLANNEL_ETCD_ENDPOINTS="http://127.0.0.1:2379"
    
    # etcd config key.  This is the configuration key that flannel queries
    # For address range assignment
    FLANNEL_ETCD_PREFIX="/atomic.io/network"
    
    # Any additional options that you want to pass
    FLANNEL_OPTIONS="--logtostderr=false --log_dir=/var/log/k8s/flannel/ --etcd-prefix=/atomic.io/network  --etcd-endpoints=http://localhost:2379 --iface=enp0s3"

    其中,enp0s3 为网卡名字,通过 ifconfig 可以查看。

    然后配置 etcd 中关于 Flannel 的 key:

    etcdctl mk /atomic.io/network/config '{ "Network": "10.0.0.0/16" }'

    其中 /atomic.io/network 要和配置文件中配置的一致。

  6. 最后启动 Flannel 并重启 Kubernetes:

    systemctl enable flanneld
    systemctl start flanneld
    systemctl restart docker
    systemctl restart kube-apiserver
    systemctl restart kube-controller-manager
    systemctl restart kube-scheduler
    systemctl restart kubelet
    systemctl restart kube-proxy

这样,一个完整的基于 K8S+Docker 的集群环境搭建完成了,后面我们就可以在这上面部署分布式系统。

本文只是做演示,不会真正的发布一套系统,因此我们以注册中心 register 为例,演示如何发布一套分布式系统。

创建 Docker 镜像

我们首先将 register 本地打包成 Jar 上传到虚拟机上,然后通过 Dockerfile 来创建 register 的镜像,Dockerfile 内容如下:

#下载java8的镜像
FROM java:8
#将本地文件挂到到/tmp目录
VOLUME /tmp
#复制文件到容器
ADD register.jar /register.jar
#暴露8888端口
EXPOSE 8888
#配置启动容器后执行的命令
ENTRYPOINT ["java","-jar","/register.jar"]

通过 docker build 构建镜像:

docker build -t register.jar:0.0.1 .

执行该命令后,会打印以下信息:

Successfully built 1aec9d5e9c70

这时通过 docker images 命令就可以看到我们刚构建的镜像:

[root@localhost ~]# docker images
REPOSITORY           TAG                 IMAGE ID            CREATED             SIZE
register.jar         0.0.1               1aec9d5e9c70        2 minutes ago       692 MB
docker.io/registry   2                   b2b03e9146e1        5 days ago          33.3 MB
docker.io/java       8                   d23bdf5b1b1b        18 months ago       643 MB

系统发布

我们本地虚拟机有了镜像就可以通过 K8S 发布了。

  1. 创建 register-rc.yaml

    apiVersion: v1
    kind: ReplicationController
    metadata:
      name: register
    spec:
      replicas: 1
      selector:
        app: register
      template:
        metadata:
          labels:
            app: register
        spec:
          containers:
          - name: register 
            image: register # 镜像名
            imagePullPolicy: IfNotPresent # 本地有镜像就不会去仓库拉取
            ports:
            - containerPort: 8888

    执行命令:

    [root@localhost ~]# kubectl create -f register-rc.yaml
    replicationcontroller "register" created

    提示创建成功后,我们可以查看 pod:

    [root@localhost ~]# kubectl get po
    NAME             READY     STATUS    RESTARTS   AGE
    register-4l088   1/1       Running   0          10s

    如果 STATUS 显示为 Running,说明运行成功,否则可以通过以下命令来查看日志:

    kubectl describe po register-4l088
  2. 然后我们通过 docker ps 命令来查看当前运行的容器:

    [root@localhost ~]# docker ps
    CONTAINER ID        IMAGE                                                        COMMAND                CREATED             STATUS              PORTS               NAMES
    dd8c05ae4432        register                                                     "java -jar /app.jar"   8 minutes ago       Up 8 minutes                            k8s_register.892502b2_register-4l088_default_4580c447-8640-11e8-bba0-080027607861_5bf71ba9
    3b5ae8575079        registry.access.redhat.com/rhel7/pod-infrastructure:latest   "/usr/bin/pod"         8 minutes ago       Up 8 minutes                            k8s_POD.43570bb9_register-4l088_default_4580c447-8640-11e8-bba0-080027607861_1f38e064

    可以看到容器已经在运行了,但是这样外部还是无法访问,因为 K8S 分配的是虚拟 IP,要通过宿主机访问,还需要创建 Service。

  3. 编写 register-svc.yaml

    apiVersion: v1
    kind: Service
    metadata:
      name: register
    spec:
      type: NodePort
      ports:
      - port: 8888
        targetPort: 8888
        nodePort: 30001 # 节点暴露给外部的端口(范围必须为30000-32767)
      selector:
        app: register

    然后执行命令:

    [root@localhost ~]# kubectl create -f register-svc.yaml
    service "register" created

    我们可以查看创建的 Service:

    [root@localhost ~]# kubectl get svc
    NAME         CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
    kubernetes   10.254.0.1       <none>        443/TCP          20h
    register     10.254.228.248   <nodes>       8888:30001/TCP   37s

    这时就可以通过 IP:30001 访问 register 了,如果访问不了需要先运行命令:

    iptables -P FORWARD ACCEPT
  4. 访问 http://172.20.10.13:30001,如图:

至此,我们的注册中心就可以通过 K8S 部署了,现在看起来比较麻烦,但是在一个大的集群环境中是很爽的,我们可以在结合前面提到的 Jenkins,把刚才一系列手动的操作交给 Jenkins 做。


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 tuyrk@qq.com

文章标题:21-第20课:K8S+Docker 部署 Spring Cloud 集群

文章字数:1.7k

本文作者:神秘的小岛岛

发布时间:2020-07-07, 16:17:12

最后更新:2020-07-14, 23:05:40

原始链接:https://www.tuyrk.cn/gitchat/springcloud-quickly/21-k8s-docker-cluster/

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录
×

喜欢就点赞,疼爱就打赏