两台Ubuntu16.04服务器:ip分别为10.145.84.68(bjyz-coparch20.epc)和10.145.84.64(bjyz-coparch21.epc)
Kubernetes版本:1.5.5
Docker版本:1.12.6
etcd版本:2.2.1
flannel版本:0.5.6
其中160服务器既做Kubernetes的master节点,又做node节点;161服务器只做node节点。
master节点上需要部署:kube-apiserver、kube-controller-manager、kube-scheduler、etcd服务。
node节点上部署:kubelet、kube-proxy、docker和flannel服务。
Client二进制下载:https://dl.k8s.io/v1.5.5/kubernetes-client-linux-amd64.tar.gz
Server二进制下载:https://dl.k8s.io/v1.5.5/kubernetes-server-linux-amd64.tar.gz
我的服务器是linux,amd64的,如果有其他环境,可以前往页面下载
将可执行文件kubernetes目录下,server和client目中的kube-apiserver、kube-controller-manager、kubectl、kubelet、kube-proxy、kube-scheduler等都拷贝到/usr/bin/目录中。
(类似zookeeper的分布式应用程序协调服务)
国内的下载包(点这里),将etcd的可执行文件etcd和etcdctl拷贝到/usr/bin/目录。
另:etcd的github release下载都是放在AWS S3上(点这里)的,除此之外,还可以自己编译etcd源码,来获取etcd的可执行文件。
(flannel用于解决同一个k8s集群内不同机器上的docker容器之间的通信,可以给一个集群定义一个子网,相同子网之间的docker容器可以相互通信)
flannel和etcd都是coreOS公司的产品,所以flannel的github release下载也是放在AWS S3上。不过幸好flannel的编译很简单,从github上下载,然后直接编译即可。然后会在flannel的bin或者dist目录下(版本不同可能导致目录不同)生成flannel可执行文件。
$ git clone -b v0.5.6 https://github.com/coreos/flannel.git
$ cd flannel $ ./build
具体的编译方法可能会不同,请参考flannel目录下的README.md文件。
将可执行文件flanneld拷贝到/usr/bin/目录。
创建/usr/bin/flannel目录,并将dist目录下的mk-docker-opts.sh文件拷贝到/usr/bin/flannel/中。
集群配置包括三个部分 etcd集群,kubernetes master,和node配置
其中,kubernetes master又包括三个部分:kube-controller-manager,kube-scheduler和kube-apiserver三个部分,其中kube-apiserver是核心模块,依赖etcd集群
后面先介绍如何配置etcd集群
(etcd本应该集群化部署,这里为了方便只做了单机部署)
$ sudo mkdir -p /var/lib/etcd/
$ sudo mkdir -p /etc/etcd/
$ sudo vim /etc/etcd/etcd.conf
ETCD_NAME=default
ETCD_DATA_DIR="/var/lib/etcd/"
ETCD_LISTEN_CLIENT_URLS="http://0.0.0.0:2379"
ETCD_ADVERTISE_CLIENT_URLS="http://10.145.84.68:2379"
$ sudo vim /lib/systemd/system/etcd.service
[Unit]
Description=Etcd Server
Documentation=https://github.com/coreos/etcd
After=network.target
[Service]
User=root
Type=notify
EnvironmentFile=-/etc/etcd/etcd.conf
ExecStart=/usr/bin/etcd
Restart=on-failure
RestartSec=10s
LimitNOFILE=40000
[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable etcd
$ sudo systemctl start etcd
$ sudo systemctl status etcd
● etcd.service - Etcd Server
Loaded: loaded (/lib/systemd/system/etcd.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2017-03-27 11:19:35 CST; 7s ago
$ netstat -apn | grep 2379
tcp6 0 0 :::2379 :::* LISTEN 7211/etcd
如下是kubernetes master三个部分的通用配置项
$ sudo mkdir /etc/kubernetes
/etc/kubernetes/config文件中,存储的是Kubernetes各组件的通用配置信息,其他组件如:kubelet,kubeproxy等还有自己的特殊配置信息,见后面。
$ sudo vim /etc/kubernetes/config
#日志很重要,务必把日志输出路径配上
KUBE_LOG_PATH="--log-dir=/var/log/kubernetes"
# false表示输出到文件
KUBE_LOGTOSTDERR="--logtostderr=false"
KUBE_LOG_LEVEL="--v=0"
KUBE_ALLOW_PRIV="--allow-privileged=false"
KUBE_MASTER="--master=http://10.145.84.68:8080"
kube-apiserver服务在Kubernetes的master主机(10.145.84.68)上。
kube-apiserver的专用配置文件为/etc/kubernetes/apiserver。
$ sudo vim /etc/kubernetes/apiserver
###
# kubernetes system config
#
# The following values are used to configure the kube-apiserver
## The address on the local server to listen to.
KUBE_API_ADDRESS="--address=0.0.0.0"
#KUBE_API_ADDRESS="--insecure-bind-address=127.0.0.1"# The port on the local server to listen on.
KUBE_API_PORT="--port=8080"# Port minions listen on
KUBELET_PORT="--kubelet-port=10250"# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://10.145.84.68:2379"# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.1.0.0/16"# default admission control policies
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota"# Add your own!
KUBE_API_ARGS=""
$ sudo vim /lib/systemd/system/kube-apiserver.service
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target
After=etcd.service
Wants=etcd.service[Service]
User=root
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/apiserver
ExecStart=/usr/bin/kube-apiserver \
$KUBE_LOG_PATH \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_ETCD_SERVERS \
$KUBE_API_ADDRESS \
$KUBE_API_PORT \
$KUBELET_PORT \
$KUBE_ALLOW_PRIV \
$KUBE_SERVICE_ADDRESSES \
$KUBE_ADMISSION_CONTROL \
$KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
kube-controller-manager的专用配置文件为/etc/kubernetes/controller-manager
$ sudo vim /etc/kubernetes/controller-manager
KUBE_CONTROLLER_MANAGER_ARGS=""
$ sudo vim /lib/systemd/system/kube-controller-manager.service
[Unit]
Description=Kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=etcd.service
After=kube-apiserver.service
Requires=etcd.service
Requires=kube-apiserver.service[Service]
User=root
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/controller-manager
ExecStart=/usr/bin/kube-controller-manager \
$KUBE_LOG_PATH \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_CONTROLLER_MANAGER_ARGS
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
kube-scheduler的专用配置文件为/etc/kubernetes/scheduler
$ sudo vim /etc/kubernetes/scheduler
KUBE_SCHEDULER_ARGS=""
$ sudo vim /lib/systemd/system/kube-scheduler.service
[Unit]
Description=Kubernetes Scheduler
Documentation=https://github.com/kubernetes/kubernetes[Service]
User=root
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/scheduler
ExecStart=/usr/bin/kube-scheduler \
$KUBE_LOG_PATH \
$KUBE_LOGTOSTDERR \
$KUBE_MASTER
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable kube-apiserver kube-controller-manager kube-scheduler
$ sudo systemctl start kube-apiserver kube-controller-manager kube-scheduler
在kubernetes集群中,在每个Node(Node又称为Minion,一个Node就是一天物理机,或者虚拟机)上会启动一个kubelet服务进程和一个proxy进程。
kubelet进程:用于处理Master节点下发到本节点的任务,管理Pod及Pod中的容器。每个kubelete进程会在api-server上注册节点自身信息,定期想Master节点汇报节点资源使用情况,并可以通过cAdvisor监控容器和节点资源。
kube-proxy进程:这个进程可以看做是Service的透明代理和负载均衡器,其核心功能是将到某个Service的访问请求转发到后端的多个Pod实例上。
Kubernetes node节点也需要配置/etc/kubernetes/config文件,内容与Kubernetes mater节点一致。
$ sudo mkdir /var/lib/kubelet
kubelet的专用配置文件为/etc/kubernetes/kubelet
$ sudo vim /etc/kubernetes/kubelet
KUBELET_LOG_DIR="--log-dir=/var/log/kubernetes"
KUBELET_ADDRESS="--address=10.145.84.68"
KUBELET_HOSTNAME="--hostname-override=10.145.84.68"
KUBELET_API_SERVER="--api-servers=http://10.145.84.68:8080"
# pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"
KUBELET_ARGS=""
$ sudo vim /lib/systemd/system/kubelet.service
[Unit]
Description=Kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=docker.service
Requires=docker.service[Service]
WorkingDirectory=/var/lib/kubelet
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/kubelet
ExecStart=/usr/bin/kubelet \
$KUBE_LOG_PATH \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBELET_API_SERVER \
$KUBELET_ADDRESS \
$KUBELET_PORT \
$KUBELET_HOSTNAME \
$KUBE_ALLOW_PRIV \
$KUBELET_POD_INFRA_CONTAINER \
$KUBELET_ARGS
Restart=on-failure
KillMode=process[Install]
WantedBy=multi-user.target
启动kubelet服务
$ sudo systemctl daemon-reload
$ sudo systemctl enable kubelet
$ sudo systemctl start kubelet
kube-proxy的专用配置文件为/etc/kubernetes/proxy
$ sudo vim /etc/kubernetes/proxy
# kubernetes proxy config
# default config should be adequate
# Add your own!
KUBE_PROXY_ARGS=""
$ sudo vim /lib/systemd/system/kube-proxy.service
[Unit]
Description=Kubernetes Proxy
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=network.target[Service]
EnvironmentFile=-/etc/kubernetes/config
EnvironmentFile=-/etc/kubernetes/proxy
ExecStart=/usr/bin/kube-proxy \
$KUBE_LOG_PATH \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_MASTER \
$KUBE_PROXY_ARGS
Restart=on-failure
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable kube-proxy
$ sudo systemctl start kube-proxy
执行kubectl get node命令来查看node状态。都为Ready状态时,则说明node节点已经成功连接到master,如果不是该状态,则需要到该节点上,定位下原因。可通过journalctl -u kubelet.service命令来查看kubelet服务的日志。
$ kubectl get node
NAME STATUS AGE
192.168.56.160 Ready 2d
192.168.56.161 Ready 2d
flannel是依赖etcd的,所以在配置flannel之前必须配置好etcd,请见3.1节
flannel的虚拟网络配置信息也是存储在etcd中,所以在启动flannel之前现在etcd中为flannel配置一个etcd网络
$ etcdctl set /coreos.com/network/config '{ "Network": "10.1.0.0/16" }'
这里选择了一个A类地址ip段作为整个K8S集群的子网,16表示子网掩码有16位1(255.255.0.0),那这个子网总共能容纳多少个容器?(10.1.0.0 & 255.255.0.0=65534)
如果部署的是etcd集群,那么每台etcd服务器上都需要执行上述步骤。但我这里只使用了standalone,所以我的etcd服务就搞定了。
$ sudo vim /etc/default/flanneld.conf
# Flanneld configuration options
# etcd url location. Point this to the server where etcd runs
FLANNEL_ETCD_ENDPOINTS="http://10.145.84.68:2379"# etcd config key. This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_PREFIX="/coreos.com/network"# Any additional options that you want to pass
#FLANNEL_OPTIONS=""
其中,FLANNEL_ETCD_PREFIX选项就是在3.1节中配置的etcd网络。
$ sudo vim /lib/systemd/system/flanneld.service
[Unit]
Description=Flanneld
Documentation=https://github.com/coreos/flannel
After=network.target
After=etcd.service
Before=docker.service[Service]
User=root
EnvironmentFile=/etc/default/flanneld.conf
ExecStart=/usr/bin/flanneld \
-etcd-endpoints=${FLANNEL_ETCD_ENDPOINTS} \
-etcd-prefix=${FLANNEL_ETCD_PREFIX} \
$FLANNEL_OPTIONS# 在flannel启动的时候为docker启动生成启动参数,主要是要让docker使用flannle网络
ExecStartPost=/usr/bin/flannel/mk-docker-opts.sh -k DOCKER_OPTS -d /run/flannel/docker
Restart=on-failure
Type=notify
LimitNOFILE=65536[Install]
WantedBy=multi-user.target
RequiredBy=docker.service
$ sudo systemctl daemon-reload
$ sudo systemctl enable flanneld
$ sudo systemctl start flanneld
$ sudo systemctl status flanneld
● flanneld.service - Flanneld
Loaded: loaded (/lib/systemd/system/flanneld.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2017-03-27 11:59:00 CST; 6min ago
通过apt来安装docker,参考这里:https://www.jianshu.com/p/c868cc306722
docker安装成功后,会自动启动dockerd进程,同时在/lib/systemd/system/docker.service可以看到docker默认的服务使用的参数
这时可以观察下docker启动默认的docker0网桥(docker启动默认使用bridge模式启动)的IP地址($ sudo ifconfig),应该是不在3.4节配置的网段中(10.1.0.0/16)
要想让docker使用flannle的网络还必须做以下事情:
$ sudo mkdir /lib/systemd/system/docker.service.d
$ sudo vim /lib/systemd/system/docker.service.d/flannel.conf
[Service]
#注意:这里的值在flannle启动时已经为docker服务生成好了,请见3.4节 EnvironmentFile=-/run/flannel/docker
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
$ sudo ps -ef | grep docker
root 1094 1 0 Dec12 ? 01:57:37 /usr/bin/dockerd --bip=10.1.40.1/24 --ip-masq=true --mtu=1472
或者通过ifconfig命令查看docker0和flannel0网桥是否在同一个网段:确实是同一网段
测试Kubernetes是否成功安装。
$ vim rc_shifangsrv.yaml
执行kubectl create命令创建ReplicationController,该ReplicationController配置中有两个副本,并且我们的环境有两个Kubernetes Node,因此,它应该会在两个Node上分别运行一个Pod。
$ kubectl create -f rc_shifangsrv.yaml
$ kubectl get pod -o wide
确实在两台Node都运行成功!
参考文献:
http://blog.csdn.net/styshoo/article/details/69220086 Ubuntu上手动安装Kubernetes
http://orchome.com/562 Docker网络及flannel介绍
http://www.10tiao.com/html/357/201704/2247485087/1.html flannel原理简析及安装