Home

CoreOS部署kubernetes

准备工作

下载Kubernetes

github下载最新的kuberbetes二进制包,这里我下载的是v1.2.4的版本。

tar zxvf kubernetes.tar.gz
cd kubernetes
// 解压amd64的版本
tar zxvf kubernetes/server/kubernetes-server-linux-amd64.tar.gz
cd kubernetes/server/kubernetes/server/bin

// 将下列文件复制到各个节点上
cp kube-apiserver kube-proxy kubelet kube-scheduler kube-controller-manager /opt/bin

将kube-apiserver kube-proxy kubelet kube-scheduler kube-controller-manager复制到各个节点上,我这里放到各个节点到/opt/bin文件夹里

启动etcd

可以参考前文。确保etcdctl命令可用。在这里我用etcd2代替etcd

配置网络

由于每个节点docker容器的ip可能是相同的,为了使不同节点上的docker容器能够互相连接,所以需要有一种方法来统一分配每个节点的docker容器ip,防止冲突,并提供不同节点容器的连接能力,也就是SDN(software defined network) kubernetes没有提供这个功能,不过有许多的kubernetes社区有许多解决方案。如flannel,calico, OVS

这里我选用CoreOS的flannel

flannel使用etcd来保存子网ip等分配,新加入节点的flanned通过访问etcd来获取一个可用的子网网段,并负责容器间的代理转发。

在CoreOS中自带flannel.service,但实际上CoreOS为了节省空间,这个service实际上是运行了一个flannel的docker容器,第一次启动时需要从网络下载flannel的镜像。由于众所周知的原因,我们还是下载编译好的二进制包吧。

https://github.com/coreos/flannel下载最新的release,解压出flanneld,同样放入/opt/bin

在所有节点/etc/systemd/system/*.service里添加flannel.service文件

[Unit]
Description=Flannel network fabric for CoreOS
Requires=etcd2.service
After=etcd2.service

[Service]
EnvironmentFile=/etc/environment
ExecStartPre=-/bin/bash -c "until /usr/bin/etcdctl set /coreos.com/network/config '{\"Network\": \"10.100.0.0/16\"}'; do echo \"waiting for etcd to become available...\"; sleep 5; done"
ExecStart=/opt/bin/flanneld -iface=$private_ipv4
ExecStartPost=-/bin/bash -c "until [ -e /run/flannel/subnet.env ]; do echo \"waiting for write.\"; sleep 3; done"
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target    

flanneld成功获取到子网网段后会以环境变量的形式保存在/run/flannel/subnet.env文件里。我们再修改docker.service

[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.com
After=docker.socket early-docker.target network.target flannel.service
Requires=docker.socket early-docker.target flannel.service

[Service]
Environment="DOCKER_CGROUPS=--exec-opt native.cgroupdriver=systemd"
EnvironmentFile=/run/flannel/subnet.env
MountFlags=slave
LimitNOFILE=1048576
LimitNPROC=1048576
ExecStartPre=-/usr/bin/ip link set dev docker0 down
ExecStartPre=-/usr/sbin/brctl delbr docker0
ExecStart=/usr/lib/coreos/dockerd daemon --host=fd:// $DOCKER_OPTS $DOCKER_CGROU --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} $DOCKER_OPTS

[Install]
WantedBy=multi-user.target

使用subnet.env中的参数启动docker service, 保证不同节点的docker容器网段不同。

配置kubernetes组件

etcd和网络配置好了以后后面的就没什么的了。 在/etc/systemd/system/*.service下创建systemd服务文件方便我们管理这些服务

在master节点创建

kube-apiserver.service

[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
Requires=etcd2.service
After=etcd2.service

[Service]
ExecStart=/opt/bin/kube-apiserver \
        --allow-privileged=true \
        --etcd-servers=http://$private_ipv4:2379 \
        --admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota \
        --insecure-bind-address=0.0.0.0 \
        --advertise-address=$private_ipv4 \
        --service-cluster-ip-range=10.100.0.0/16 \
        --runtime-config=extensions/v1beta1/daemonsets=true,extensions/v1beta1/deployments=true,extensions/v1beta1/ingress=true \
        --logtostderr=true
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

kube-controller-manager.service

[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
Requires=kube-apiserver.service
After=kube-apiserver.service

[Service]
ExecStart=/opt/bin/kube-controller-manager \
        --master=$private_ipv4:8080 \
        --logtostderr=true
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

kube-scheduler.service

[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
Requires=kube-apiserver.service
After=kube-apiserver.service

[Service]
ExecStart=/opt/bin/kube-scheduler --master=$private_ipv4:8080 --logtostderr=true
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

在node节点创建

kubelet.service

[Unit]
 Description=Kubernetes Kubelet
 Documentation=https://github.com/kubernetes/kubernetes
 After=docker.service
 Requires=docker.service

 [Service]
 ExecStartPre=/usr/bin/mkdir -p /etc/kubernetes/manifests
 ExecStart=/opt/bin/kubelet \
        --address=0.0.0.0 \
        --allow-privileged=true \
        --cluster-dns=10.100.0.10 \
        --cluster-domain=cluster.local \
        --config=/etc/kubernetes/manifests \
        --hostname-override=$private_ipv4 \
        --api-servers=http://<API_SERVER_IP>:8080 \
        --pod-infra-container-image="kubernetes/pause" \
        --network-plugin-dir=/etc/cni/net.d \
        --network-plugin=cni \
        --logtostderr=true
 Restart=always
 RestartSec=10

 [Install]
 WantedBy=multi-user.target

kube-proxy.service

Unit]
Description=Kubernetes Proxy
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
Requires=kubelet.service
After=kubelet.service

[Service]
ExecStart=/opt/bin/kube-proxy \
        --master=http://<API_SERVER_IP>:8080 \
        --proxy-mode=iptables \
        --logtostderr=true
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

部分替换成master的ip

小试牛刀

启动上面的所以service kubernetes集群应该就搭建起来了。我们来测试一下

新建一个nginx.yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-nginx
spec:
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx:alpine
        ports:
        - containerPort: 80

执行

> create -f ./nginx.yaml
// 查看pod运行状况
> kubectl get pods -l run=my-nginx -o wide
NAME                        READY     STATUS    RESTARTS   AGE       NODE
my-nginx-2643493705-274ab   1/1       Running   0          1m        192.168.64.9
my-nginx-2643493705-8wr06   1/1       Running   0          1m        192.168.64.109

我们可以看到启动了两个nginx的pod

查看每个pod的ip

> kubectl get pods -l run=my-nginx -o yaml | grep podIP
    podIP: 10.100.73.2
    podIP: 10.100.63.2

我们在内任一台机上执行

> curl http://10.100.73.2

应该会看到nginx的欢迎页面打印出来。


参考资料

[1]http://qiankunli.github.io/2015/01/29/Kubernetes_installation.html

[2]https://github.com/shenshouer/calico-kubernetes

[3]http://qinghua.github.io/kubernetes-in-mesos-8/

[4]http://kubernetes.io/docs/user-guide/connecting-applications/