# CentOS 7 + Kubernetes 1.1.x  + Docker 1.9.x  安装指南

## 前言

[Docker](http://docker.io/) 和 [Kubernates](http://kubernetes.io/)最近可以说红的发紫，各种大部头和高深研究也层出不穷。

学习过程中看了官网和社区提供的不少起步文档，但是手工半手工这一块，总感觉语焉不详，操作性不很好，因此就边学边记，整理成这么一篇东西，本文只涉及操作，理论、架构、前景等内容，还请读者自行翻阅相关材料。

> 注意这里按照我的个人习惯，会把所有可执行文件复制到 `/usr/local/share`，并链接到 `/usr/local/bin`；环境配置文件统一放置到 `/etc/sysconfig/kubernetes` 中，这个做法跟手工安装一样，纯属个人恶趣味，没什么具体理由。

## 环境准备

这里我们使用的是 CentOS 7 为例子。

接下来内容里面会使用 A, B 两台服务器：

* 服务器 A
    
    * IP: 10.211.55.12
        
    * 职责
        
        * Kubernate Master
            
        * Docker Private Registry
            
        * Kubernate Master UI
            
        * Kubernate Node
            
        * ETCD
            
* 服务器 B
    
    * IP: 10.211.55.13
        
    * 职责
        
        * Kubernate Node
            

### ETCD （仅 Master 需要）

可以简单理解为，用来管理容器 IP 的数据库。

[Github 地址](https://github.com/coreos/etcd)

使用 Yum 直接安装：

`yum install -y etcd;`

> 注意：安装后需要修改 `/etc/etcd/etcd.conf`，将其中的监听地址由 `127.0.0.1` 改为 `0.0.0.0` 或者其他 Node 可以访问的地址。

```bash
# 启动服务
systemctl daemon-reload
systemctl enable etcd
systemctl start etcd

# 为后续服务提供初始值
etcdctl mk /docker.intranet/network/config '{"Network":"192.168.0.0/16"}'
```

### Flannel (所有服务器都需要)

对前面的 ETCD 有依赖，这里利用这一服务来为 Docker 提供网络分配和部分网络参数生成的任务。

`yum install -y flannel`

接下来编辑配置文件 `/etc/sysconfig/flanneld`，将其中的 `FLANNEL_ETCD` 地址修改为之前我们配置的地址，并修改 `FLANNEL_ETCD_KEY` 为我们使用 etcdctl 设置的值，上文中是 **"docker.intranet"**

```bash
# 启动服务
systemctl daemon-reload
systemctl enable flanneld
systemctl start flanneld
```

---

## Kubernates Master

### 下载和安装

首先下载压缩包，并复制其中需要的文件，然后做符号链接到习惯位置。

```bash
wget https://github.com/kubernetes/kubernetes/releases/download/v1.1.3/kubernetes.tar.gz
cd kubernetes/server
tar xf kubernetes-server-linux-amd64.tar.gz
cp -Rf kubernetes/ /usr/local/share
cp kubernetes/cluster/centos/node/scripts/remove-docker0.sh /usr/local/share/kubernetes/server/bin
cd /usr/local/bin
ln -s /usr/local/share/kubernetes/server/bin/hyperkube
ln -s /usr/local/share/kubernetes/server/bin/kube-apiserver
ln -s /usr/local/share/kubernetes/server/bin/kube-controller-manager
ln -s /usr/local/share/kubernetes/server/bin/kubectl
ln -s /usr/local/share/kubernetes/server/bin/kubelet
ln -s /usr/local/share/kubernetes/server/bin/kube-proxy
ln -s /usr/local/share/kubernetes/server/bin/kube-scheduler
ln -s /usr/local/share/kubernetes/server/bin/linkcheck
ln -s /usr/local/share/kubernetes/server/bin/remove-docker0.sh
```

主控服务器 A 除去前面提到的 ETCD 和 FlannelD 两个服务之外，需要三个服务

* API Server
    
* Controller Manager
    
* Scheduler
    

前面下载的包解压之后，`kubernetes/cluster/centos/master/scripts` 中有以下脚本分别对应上面三个必要的服务：

* apiserver.sh
    
* controller-manager.sh
    
* scheduler.sh
    

> 这几个脚本大概看了一下，是自动安装过程的一部分，这里拿来进行修改，以适应我们自己的环境，方便应用，也有利于学习，并最终生成一个符合自己洁癖的环境:D

### apiserver.sh

* `MASTER_ADDRESS` 取值为服务器 A 的地址
    
* `ETCD_SERVERS` 取值为ETCD的完整网址
    
* `SERVICE_CLUSTER_IP_RANGE` 中的内容，按照之前我们给 ETCD 初始化的 IP 范围来设置。
    
* 修改过时用法：`KUBE_API_ADDRESS="--insecure-bind-address=${MASTER_ADDRESS}"`
    
* 修改过时用法：`KUBE_API_PORT="--insecure-port=8080"`
    
* `cat <<EOF` 所在行涉及的文件名，按照个人习惯更改
    
* 用于服务定义的 service 文件，其中的 `ExecStart` 要注意修改为我们之前生成连接的位置。
    

最后把涉及证书的一块删掉，这部分内容比较繁杂，先砍掉为好

```bash
KUBE_APISERVER_OPTS="   \${KUBE_LOGTOSTDERR}         \\
                        \${KUBE_LOG_LEVEL}           \\
                        \${KUBE_ETCD_SERVERS}        \\
                        \${KUBE_API_ADDRESS}         \\
                        \${KUBE_API_PORT}            \\
                        \${MINION_PORT}              \\
                        \${KUBE_ALLOW_PRIV}          \\
                        \${KUBE_SERVICE_ADDRESSES}   \\"
```

编辑结束之后，运行该脚本，也就完成了 API SERVER 的配置。

> 语法错误等情况是在所难免的，可以使用 `systemctl status -l [服务名称]` 来检查出错信息，如果信息不够详尽，可以把所生成的环境文件中的 `loglevel` 设置为 0。
> 
> 另外还可以直接把 ExecStart 中的最终内容直接在命令行执行进行除错。

### controller-manager.sh 和 scheduler.sh

* 修改 `MASTER_ADDRESS`
    
* 修改文件位置
    
* 执行
    

> 走到这里，就可以使用 `kubectl get nodes` 之类的命令来跟 Master 互动了，浏览器也可以在服务器的 8080 端口获得一点没用的基本信息了。

### Docker

> 本不想在 Master 机安装 Docker，但是后面的 Kubernates UI，如果不涉及网络操作的话，似乎必须在 Master 上运行，所以只能如此处理了。

Docker 这里我们使用 Docker.io 提供的官方源进行安装：

```bash
# !bin/sh
tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

yum update -y
yum install -y docker-engine
systemctl daemon-reload
systemctl enable docker
```

这个配置就不准备使用脚本生成了，会稍微麻烦一些，简单粗暴上代码：

* 首先创建文件 `/etc/systemd/system/docker.service.d/custom.conf` 这个文件会覆盖 docker.service 中的部分内容
    

```plaintext
[Service]
Environment="HTTP_PROXY=10.211.55.2:8016" "NO_PROXY=localhost,center.docker.local,16.158.51.247"
EnvironmentFile=-/run/flannel/docker
EnvironmentFile=-/etc/sysconfig/kubernetes/docker
ExecStartPre=/usr/local/bin/remove-docker0.sh
```

上面文件中包含了代理的设置，用于在公司内网环境下，使用代理服务器获取外部仓库的内容。 两行`EnvironmentFile`，其中一个是我们自行编写的 Docker 环境文件，另一个则是 flannel 运行生成的配置文件，而 `ExecStartPre` 则是从 Kubernetes 压缩包中的 Docker 配置内容中抄来的，修改了文件位置而已。

上面看出，Docker 服务对 Flanneld 服务是有依赖的，经过对 `systemctl status docker` 的观察，可以看到这一服务在 `/usr/lib/systemd/system/docker.service.d` 生成了一份文件，用于声明这一依赖关系。

编辑这个文件：`/etc/systemd/system/multi-user.target.wants/docker.service` 如果位置不同，可以使用 `find /etc -name 'docker.service'`，ExecStart 一行改为 `ExecStart=/usr/bin/docker daemon $DOCKER_OPT_BIP $DOCKER_OPT_MTU $DOCKER_OPTS`

```bash
systemctl daemon-reload
systemctl enable docker
systemctl start docker
```

## Node

同样的，可以在 `kubernetes/cluster/centos/node/scripts` 找到两个 Node 服务的配置脚本，这里先后修改运行 `kubelet.sh` 以及 `proxy.sh` 即可。

## Kubeletes UI

Kubeletes UI 的安装很简单：

```bash
kubectl create -f cluster/addons/kube-ui/kube-ui-rc.yaml --namespace=kube-system
kubectl create -f cluster/addons/kube-ui/kube-ui-svc.yaml --namespace=kube-system
```

运行之后，可以使用 `kubectl get pods --all-namespace` 查看进展状况，第一次创建，会到 Google 仓库下载基础镜像，前面介绍的代理使用技巧可能就派上用场了。等到状态从 Pending 变为 Running 之后，就可以用浏览器访问 `http://master:8080/ui` 来查看控制台了。
