文章目录
  1. 1. 准备工作
  2. 2. 搭建网络环境
  3. 3. 搭建k8s环境
  4. 4. 测试k8s环境

Kubernetes简称k8s,是谷歌于2014年开始主导的开源项目,提供了以容器为中心的部署、伸缩和运维平台。截止目前它的最新版本为1.2。搭建环境之前建议先了解一下kubernetes的相关知识,可以参考《如果有10000台机器,你想怎么玩?》系列文章。本文从零开始搭建一个kubernetes集群。

准备工作

我们需要先安装virtualBoxvagrant。通过vagrant来驱动virtualBox搭建一个虚拟测试环境。首先在本地任意路径新建一个空文件夹比如test,运行以下命令:

virtual box host
1
2
3
4
mkdir test
cd test
vagrant init minimum/ubuntu-trusty64-docker
vi Vagrantfile

里面应该有一句config.vm.box = "minimum/ubuntu-trusty64-docker",在它的下面添加如下几行代码,相当于给它分配三台虚拟机,一台叫做master,它的IP是192.168.33.17;另两台叫做node1node2,它们的IP是192.168.33.18192.168.33.19

Vagrantfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
config.vm.define "master" do | host |
host.vm.hostname = "master"
host.vm.network "private_network", ip: "192.168.33.17"
host.vm.provider "virtualbox" do |v|
v.memory = 1024
end
end
config.vm.define "node1" do | host |
host.vm.hostname = "node1"
host.vm.network "private_network", ip: "192.168.33.18"
host.vm.provider "virtualbox" do |v|
v.memory = 2048
end
end
config.vm.define "node2" do | host |
host.vm.hostname = "node2"
host.vm.network "private_network", ip: "192.168.33.19"
host.vm.provider "virtualbox" do |v|
v.memory = 2048
end
end

这个vagrant镜像已经在ubuntu的基础上帮我们安装了docker,用起来很方便。然后分别在三个终端运行以下命令启动并连接三台虚拟机。

virtual box host terminal 1
1
2
vagrant up
vagrant ssh master

virtual box host terminal 2
1
vagrant ssh node1
virtual box host terminal 3
1
vagrant ssh node2

这个vagrant镜像默认的docker版本为1.9.0,如果你愿意,可以用下面的命令将其升级为1.10.3,但这不是必须的:

all or none
1
2
3
4
5
6
7
8
sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
sudo sh -c "echo deb https://apt.dockerproject.org/repo ubuntu-trusty main > /etc/apt/sources.list.d/docker.list"
sudo apt-get update
sudo apt-get purge lxc-docker
sudo apt-cache policy docker-engine
sudo apt-get install docker-engine
sudo service docker restart
docker -v

搭建网络环境

为了打通不同主机上的容器的网络连接,最简单的方法是安装一个覆盖网络,这里我们使用flannel。它使用etcd来配置,所以我们需要先运行一个etcd实例。下面在master虚拟机上用容器运行一个etcd实例:

master
1
2
3
4
5
6
7
8
9
10
docker run -d \
--net=host \
--restart=always \
--name=etcd \
-v /var/etcd/data:/var/etcd/data \
kubernetes/etcd:2.0.5 \
/usr/local/bin/etcd \
--addr=192.168.33.17:4001 \
--bind-addr=0.0.0.0:4001 \
--data-dir=/var/etcd/data

接下来往etcd里插入flannel的配置数据。这里指定flannel可以使用的IP地址为10.0.0.0/8区间:

master
1
docker exec -it etcd etcdctl set /qinghua.github.io/network/config '{"Network": "10.0.0.0/8"}'

然后安装并在后台运行flannel:

master node1 node2
1
2
3
4
wget -c https://github.com/coreos/flannel/releases/download/v0.5.5/flannel-0.5.5-linux-amd64.tar.gz
tar zxvf flannel-0.5.5-linux-amd64.tar.gz
sudo flannel-0.5.5/flanneld --etcd-endpoints=http://192.168.33.17:4001 --etcd-prefix=/qinghua.github.io/network --iface=eth1 > flannel.log 2>&1 &
cat flannel.log

Flannel启动完成后,会获得一个可用于分配的IP集合,并存放到/run/flannel/subnet.env里。我们需要配置一下docker的可用IP为可用于分配的IP:

master node1 node2
1
2
3
source /run/flannel/subnet.env
sudo sh -c "echo DOCKER_OPTS=\\\"--bip=$FLANNEL_SUBNET --mtu=$FLANNEL_MTU\\\" >> /etc/default/docker"
sudo service docker restart

搭建k8s环境

终于轮到k8s啦。首先需要下载并解压kubernetes 1.2.0版:

master node1 node2
1
2
3
wget -c https://github.com/kubernetes/kubernetes/releases/download/v1.2.0/kubernetes.tar.gz
tar zxvf kubernetes.tar.gz
tar zxvf kubernetes/server/kubernetes-server-linux-amd64.tar.gz

解压出来的文件里面含了一些启动master需要的docker镜像文件,将它们导入:

master
1
2
3
4
docker load -i kubernetes/server/bin/kube-apiserver.tar
docker load -i kubernetes/server/bin/kube-controller-manager.tar
docker load -i kubernetes/server/bin/kube-scheduler.tar
docker images

有条件科学上网的童鞋可以自行准备gcr.io/google_containers/etcd:2.2.1这个镜像,否则就凑合着使用先前的kubernetes/etcd:2.0.5。注意,这里为了简单起见,使用同一套etcd。真实环境里,flannel和kubernetes使用的etcd是分开的。接下来开始启动api server:

master
1
2
3
4
5
6
7
8
docker run -d \
--name=apiserver \
--net=host \
gcr.io/google_containers/kube-apiserver:e68c6af15d4672feef7022e94ee4d9af \
kube-apiserver \
--insecure-bind-address=192.168.33.17 \
--service-cluster-ip-range=11.0.0.0/16 \
--etcd-servers=http://192.168.33.17:4001

然后是controller manager:

master
1
2
3
4
5
docker run -d \
--name=cm \
gcr.io/google_containers/kube-controller-manager:b9107c794e0564bf11719dc554213f7b \
kube-controller-manager \
--master=192.168.33.17:8080

最后是scheduler:

master
1
2
3
4
5
docker run -d \
--name=scheduler \
gcr.io/google_containers/kube-scheduler:903b34d5ed7367ec4dddf846675613c9 \
kube-scheduler \
--master=192.168.33.17:8080

服务器启动完毕,可以运行以下命令来查看版本,咱们用的是1.2:

master
1
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 version

接下来该客户端了。首先启动kubelet:

node1 node2
1
2
3
NODE_IP=`ifconfig eth1 | grep 'inet addr:' | cut -d: -f2 | cut -d' ' -f1`
sudo kubernetes/server/bin/kubelet --api-servers=192.168.33.17:8080 --node-ip=$NODE_IP > kubelet.log 2>&1 &
cat kubelet.log

Kubelet启动完成后,在master上就可以看到了:

master
1
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 get no

最后启动kube-proxy:

node1 node2
1
2
sudo kubernetes/server/bin/kube-proxy --master=192.168.33.17:8080 > proxy.log 2>&1 &
cat proxy.log

测试k8s环境

环境安装好了,接下来试着启动一个pod。启动之前,由于kubernetes需要通过gcr.io/google_containers/pause:2.0的小镜像来管理pod的网络。在解压出来的kubernetes文件夹里可以导入:

node1 node2
1
docker load -i kubernetes/addons/gcr.io~google_containers~pause:2.0.tar

然后就可以用命令行在任意一台虚拟机上运行一个tomcat,并生成服务:

master
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
cat << EOF >tomcat.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: tomcat
spec:
replicas: 1
selector:
app: tomcat
template:
metadata:
name: tomcat
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: tomcat:8.0.30-jre8
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: tomcat
labels:
app: tomcat
spec:
type: NodePort
selector:
app: tomcat
ports:
- port: 80
targetPort: 8080
nodePort: 30088
EOF
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 create -f tomcat.yaml

一开始由于需要下载tomcat镜像可能会慢点,随时可以用下面的命令来查看进度:

master
1
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 describe po tomcat

可以用下面的命令来查看pod、replication controller、service和endpoint:

master
1
2
3
4
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 get po
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 get rc
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 get svc
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 get ep

我们看到的endpoint里,应该有一个tomcat。在我的虚拟机上它的ENDPOINTS是10.0.8.3:8080,访问一下:

1
2
3
POD_IP=`kubernetes/server/bin/kubectl -s 192.168.33.17:8080 get ep tomcat -o jsonpath={.subsets[*].addresses[*].ip}`
echo $POD_IP
curl $POD_IP:8080

顺利的话,这三台虚拟机任意一台都可以访问这个tomcat的endpoint。由于启动这三台vagrant虚拟机的主机上并没有安装flannel,所以目前就别想用主机的浏览器打开这个网址啦。但是,由于我们创建服务的时候类型设置为NodePort,这样外部是可以通过任意node的特定端口访问这个服务的。也就是说,下面这两个url都是可以在集群外部访问的,并且效果一样:

初步测试完毕,可以使用以下命令来删除刚才创建的tomcat系列对象:

master
1
kubernetes/server/bin/kubectl -s 192.168.33.17:8080 delete -f tomcat.yaml

文章目录
  1. 1. 准备工作
  2. 2. 搭建网络环境
  3. 3. 搭建k8s环境
  4. 4. 测试k8s环境