07月28, 2018

如何在国内安装K8S

Kubernetes V1.10.6部署备忘

如何在国内安装K8S(v1.10.6 release)

简介

出于对分布式系统的好奇,以及做毕设系统的需要,我最近在研究K8S。但是首先,我就被卡在了第一道关卡——安装上。k8s是Google发布的开源工具,很多包都是放在google的服务器上,于是在Ubuntu上安装的时候,就各种被墙,非常的烦。开始写这篇文章的时候我还没成功安装上,为了给以后做参考,我决定把安装步骤记下来。

基本环境

两台以上的机器,已经处于一个内网中
系统为Ubuntu 16.04的lts版本

安装步骤

Step1:准备梯子,设置代理

这一步没什么说的,可以使用已有的梯子,也可以自己搭,我是自己搭建了一个梯子,使用的是秋水逸冰大佬的脚本。
之后在需要安装k8s的机器上设置客户端,这里需要使用shadowsocks-libev中的ss-redir。
参考我的另外一篇文章: 如何在ubuntu上配置透明代理(全局翻墙)

Step2:安装docker

首先移除旧版本

sudo apt-get remove docker docker-engine docker.io

更新apt包索引

sudo apt update

安装https支持包

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common

添加Docker官方GPG key

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

添加稳定版的仓库源(按架构选择)

  • amd64:
    sudo add-apt-repository \\
     "deb [arch=amd64] https://download.docker.com/linux/ubuntu \\
     $(lsb_release -cs) \\
     stable"
  • armhf:
    sudo add-apt-repository \\
     "deb [arch=armhf] https://download.docker.com/linux/ubuntu \\
     $(lsb_release -cs) \\
     stable"
  • s390x:
    sudo add-apt-repository \\
     "deb [arch=s390x] https://download.docker.com/linux/ubuntu \\
     $(lsb_release -cs) \\
     stable"

更新apt包索引

sudo apt update

安装(安装慢?可以尝试下切换apt源)

sudo apt-get install docker-ce

添加用户到组(不做这一步安装会出错)

sudo groupadd docker 
sudo usermod -aG docker $USER

一般来说安装完docker就启动了

Step3:安装K8S

从github下载release文件,与早期版本(1.4以前)不一样的是,现在不再直接下载二进制文件(动辄1.3G+的文件),而是下载一组脚本,用户把脚本下载到本地之后,启动脚本再下载二进制文件。 下载地址:https://github.com/kubernetes/kubernetes/releases

下载后,解压包,执行

bash cluster/get-kube-binaries.sh

之后所有的可执行文件都会出现在server目录下,把一个名为kubernetes-server-linux-amd64.tar.gz的压缩包解压

tar -xzvf kubernetes-server-linux-amd64.tar.gz

得到名为kubernetes的目录,所有的二进制文件都在kubernetes/server/bin 路径下。 接下来的部署分为两部分,分别部署Master节点和Node节点。

Master

安装etcd

首先需要单独安装etcd,从etcd的github下载etcd的二进制文件,然后把etcdetcdctl复制到/usr/bin目录下(需要root权限),并在/usr/lib/systemd下创建system目录,添加服务文件/usr/lib/systemd/system/etcd.service

[Unit]
Description=ETCD Server
After=network.target

[Service]
Type=simple
WorkingDirectory=/var/lib/etcd
EnvironmentFile=-/etc/etcd/etcd.conf
ExecStart=/usr/bin/etcd

[Install]
WantedBy=multi-user.target

WorkingDirectory表示etcd数据文件的存放路径,需要在启动前创建好。 然后执行命令,启动etcd并加为自启动服务。

sudo systemctl daemon-reload
sudo systemctl enable etcd
sudo systemctl start etcd

通过执行etcdctl cluster-health,来确认是否启动成功

member 8e9e05c52164694d is healthy: got healthy result from http://localhost:2379
cluster is healthy
安装kubernetes Master的各项组件

需要将kubernetes/server/bin路径下kubectlkube-apiserverkube-controller-managerkube-scheduler都拷贝到/usr/bin目录下。然后接下来配置他们对应的服务,在/usr/lib/systemd/system下添加以下文件:

  • kube-apiserver.service:
    [Unit]
    Description=Kubernetes API Server
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=etcd.service
    Wants=etcd.service
    [Service]
    EnvironmentFile=/etc/kubernetes/apiserver
    ExecStart=/usr/bin/kube-apiserver $KUBE_API_ARGS
    Restart=on-failure
    Type=notify
    LimitNOFILE=65536
    [Install]
    WantedBy=multi-user.target
  • kube-controller-manager.service
    [Unit]
    Description=Kubernetes Controller Manager
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=kube-apiserver.service
    Requires=kube-apiserver.service
    [Service]
    EnvironmentFile=/etc/kubernetes/controller-manager
    ExecStart=/usr/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_ARGS
    Restart=on-failure
    LimitNOFILE=65536
    [Install]
    WantedBy=multi-user.target
  • kube-scheduler
    [Unit]
    Description=Kubernetes Scheduler
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=kube-apiserver.service
    Requires=kube-apiserver.service
    [Service]
    EnvironmentFile=/etc/kubernetes/scheduler
    ExecStart=/usr/bin/kube-scheduler $KUBE_SCHEDULER_ARGS
    Restart=on-failure
    LimitNOFILE=65536
    [Install]
    WantedBy=multi-user.target

然后创建/etc/kubernetes目录,并添加各项组件的配置文件(文件名与上一段中的EnvironmentFile相对应)

  • apiserver
    KUBE_API_ARGS="--etcd-servers=http://localhost:2379 --insecure-bind-address=0.0.0.0 --insecure-port=8080 --service-cluster-ip-range=169.169.0.0/16 --service-node-port-range=1-65535 --admission-control=NamespaceLifecycle,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
  • controller-manager
    KUBE_CONTROLLER_MANAGER_ARGS="--master=http://10.0.0.105:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"
  • scheduler
    KUBE_SCHEDULER_ARGS="--master=http://10.0.0.105:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"

最后,依次启动各项服务

sudo systemctl daemon-reload
sudo systemctl enable kube-apiserver.service
sudo systemctl start kube-apiserver.service
sudo systemctl enable kube-controller-manager.service
sudo systemctl start kube-controller-manager.service
sudo systemctl enable kube-scheduler.service
sudo systemctl start kube-scheduler.service

可以使用systemctl status来验证各项服务的启动状态。

Node

kubernetes/server/bin下的kubectlkube-proxykubelet拷贝到/usr/bin/目录下。 同样是要创建/usr/lib/systemd/system/etc/kubernetes这两个目录。然后创建对应的服务配置文件.

  • kube-proxy.service

    [Unit]
    Description=Kubernetes Kube-Proxy Server
    Documentation=https://github.com/GoogleCloudPlatform/kubernetes
    After=network.target
    Requires=network.target
    [Service]
    EnvironmentFile=/etc/kubernetes/proxy
    ExecStart=/usr/bin/kube-proxy $KUBE_PROXY_ARGS
    Restart=on-failure
    LimitNOFILE=65536
    [Install]
    WantedBy=multi-user.target
  • kubelet.service

    [Unit]
    Description=Kubernetes Kubelet Server
    DocumentationFile=https://github.com/GoogleCloudPlatform/kubernetes
    After=docker.service
    Require=docker.service
    [Service]
    WorkingDirectory=/var/lib/kubelet
    ExecStart=/usr/bin/kubelet --kubeconfig=/etc/kubernetes/kubelet
    Restart=on-failure
    [Install]
    WantedBy=multi-user.target

再在/etc/kubernetes目录下创建对应的配置文件
proxy

KUBE_PROXY_ARGS="--master=http://[Your Master IP]:8080 --logtostderr=false --log-dir=/var/log/kubernetes --v=2"

kubelet

apiVersion: v1
clusters:
- cluster:
    server: http://[Your Master IP]:8080
  name: default-cluster
contexts:
- context:
    cluster: default-cluster
    user: default-admin
  name: default-context
current-context: default-context
kind: Config
preferences: {}
users: []

Your Master IP换成你的Master节点的IP。 这里要注意,有些旧版的教程里,会为kubelet设置类似于--api-servers这样的参数,但是这些参数在新版本里已经都被去掉了,需要设置--kubeconfig并将值设为对应的配置文件路径。

最后,启动这两个服务

sudo systemctl daemon-reload
sudo systemctl enable kubelet.service
sudo systemctl start kubelet.service
sudo systemctl enable kube-proxy.service
sudo systemctl start kube-proxy.service

成功之后,在Master上执行kubectl get nodes就能看到Node节点

NAME              STATUS    ROLES     AGE       VERSION
vm-0-104-ubuntu   Ready     <none>    48m       v1.10.6

后记

Kubernetes安装是一个非常麻烦的事情,而且迭代速度快,有很多坑,但是依然有很多人去踩,为什么?

虽然还没深入底层去研究他的实现原理,不过对于k8s所能提供的一种业务形态有了一个大致的认识。

严格来说,k8s并不能在实际的业务代码上提供任何的帮助,业务逻辑依然是由开发者自己写,甚至可能会有一些限制,在k8s上部署的业务,都必须是容器化的,这样,k8s才能帮我们处理业务以外,与架构和性能相关的很多东西。比如水平扩容,负载均衡,自动恢复,服务发现,或者第三方在这基础之上开发的灰度发布,熔断,限流等等。k8s比ansible提供了更强的集群驾驭能力。

另外,k8s可以帮助开发者处理与业务内部逻辑无关的问题,比如利用k8s去设计鉴权,去设计负载平衡,去设计调度,也需要开发者自己拿捏k8s和业务之间在一些问题上的选择,比如如果是在k8s上架设了spark,那么就有在资源层面谁调度谁这样的问题。

在我个人看来,软件系统发展的过程中,前一个阶段很复杂的东西会在下一个阶段中被模块化,或者组件化,进而为后来的开发者们提供更高层次的抽象能力。

为什么C++和C只有在我们需要提升核心性能的时候才会考虑,因为为了构建更加复杂的系统,Go或者Python能帮我们完成很多底层与业务无关的事情,比如处理网络通信等。

而在k8s这个层次,举一个例子,我们原来可能说部署一个CRM或者OA本身就是一个可以被称之为复杂的系统的东西,但是当我们把CRM和OA分别封装到容器里之后,我们能借助这些容器化的子系统在k8s上搭建出一整个企业信息化平台。

云平台会是下一个阶段的抽象能力,目前已有部分混合云的业务出现,可能下一个阶段的软件系统,将建立在多云基础上进行开发。

安利

如果不是为了研究k8s的原理,只是为了部署业务的话,不想自己操作这些复杂的步骤,建议可以试用一下青云Kubesphere

Citation

黄超

清华大学软件学院
thss15_huangc@163.com

北京旷视科技有限公司
huangchao@megvii.com

Reference

本文链接:https://blog.magichc7.com/post/how-to-install-kubernetes-in-China.html

-- EOF --

相关评论