前言
在探索容器應(yīng)用治理的過程中,我們進行了很多的實踐,我們嘗試了CoreOS的Fleet、Docker Swarm,我們也參考了諸多廠商的Docker集群實踐方案,最終我們發(fā)現(xiàn)在絕大部分的成熟應(yīng)用案例中,Kubernetes似乎是相當好的選擇。它提供的應(yīng)用部署、維護、 擴展機制等功能,可以方便地管理跨主機運行容器化的應(yīng)用,Kubernetes背后有Google,RedHat,CoreOS等諸多大公司的支持。
架構(gòu)
本次部署我們采用的是單Master多Minion結(jié)構(gòu),下面是我的部署全過程,希望能給讀者提供一些思路,如果有任何更好的方法或者有其他方案討論,歡迎使用Email或者Github留言。
資源
操作系統(tǒng): CentOS Linux release 7.2.1511 (Core)
容器引擎: Docker(Kubernetes還支持Rkt)
容器網(wǎng)絡(luò): Flannel
部署形式: 1主多從(Master沒做HA),主機Systemd運行方式(Kubernetes還支持容器部署和單機部署),單集群(Kubernetes還支持多集群部署)。
資源下載
Docker初始化
主要是對Kubernetes Minion節(jié)點進行一些配置初始化,有一些配置是必須的,有一些配置不是必須的,接下來我會標記好,當然配置可能還有更好的方式,大家可以自行研究。
清除防火墻規(guī)則和關(guān)閉Selinux
iptables -X
iptables -F
iptables -Z
vim /etc/sysconfig/selinux
SELINUX=disabled #如果你有比較高的安全要求,不建議關(guān)閉Selinux,在配置和使用Kubernetes的過程中配置好相應(yīng)Selinux條文即可
配置Docker存儲
默認CentOS7下Docker使用的Device Mapper設(shè)備默認使用loopback設(shè)備,從網(wǎng)友們的反饋看來,這個存儲的問題比較多,官方也不推薦使用這一種存儲方式,如果你只是做測試,可以省略修改,以下是docker存儲方式修改為direct-lvm的方式,完整的手工配置比較復雜,可以參考Docker and the Device Mapper storage driver。在CentOS7中,提供了docker-storage-setup工具用于簡化配置,準備一個空磁盤,以下我使用的是vdb.。
編輯/etc/sysconfig/docker-storage-setup文件加入以下內(nèi)容
DEVS=/dev/vdb
VG=dk-vg
SETUP_LVM_THIN_POOL=yes
然后關(guān)閉Docker,并生成相應(yīng)的分區(qū),清理舊數(shù)據(jù),再啟動Docker。
systemctl stop docker
docker-storage-setup
rm -rf /var/lib/docker
systemctl start docker
這時候,通過Docker info|grep "Pool Name"應(yīng)該可以看到存儲信息,便可以判斷是否配置成功。
添加私有倉庫
如果你有自己的私有倉庫,又沒有配置登錄設(shè)置,那么你需要修改配置文件允許你的Docker訪問私有倉庫
編輯/etc/sysconfig/docker,為Docker選項加入配置.
#支持多個私有倉庫地址
OPTIONS='--insecure-registry 10.201.78.110:5000 --insecure-registry 10.201.78.111:5000 --log-driver=journald'
內(nèi)核參數(shù)
以下參數(shù)用于開啟Linux內(nèi)核的一些橋接網(wǎng)卡的Iptables功能。
vim /etc/sysctl.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1
sysctl -p
#同樣也可以在docker info中看到是否看起成功,無須重啟
配置etcd
Kubernetes和flannel都需要用到etcd,所以我們先配置好etcd,你可以選擇集群或者單機模式,以下我配置etcd為三節(jié)點集群(通常建議節(jié)點數(shù)為3、5、7,利于集群內(nèi)的選舉)。下載的etcd是編譯號的二進制文件,可直接運行,方便起見,你只需要將etcd和etcdctl文件放到/usr/bin或/bin中
編輯/usr/lib/systemd/system/etcd.service文件,并啟動etcd。
[Unit]
Description=etcd
[Service]
ExecStart=/usr/bin/etcd --name infra0 --initial-advertise-peer-urls http://10.201.78.110:7001 \
--listen-peer-urls http://10.201.78.110:7001 \
--listen-client-urls http://10.201.78.110:4001,http://127.0.0.1:4001 \
--advertise-client-urls http://10.201.78.110:4001 \
--initial-cluster-token etcd-cluster \
--initial-cluster infra0=http://10.201.78.110:7001,infra1=http://10.201.78.111:7001,infra2=http://10.201.78.112:7001 \
--data-dir /apps/data/etcd \
--initial-cluster-state new
[Install]
WantedBy=multi-user.target
確認啟動沒有報錯后,其他兩個節(jié)點編輯同樣的文件,修改節(jié)點名(這里的"infra0")和IP地址,然后啟動etcd便可以了,你可以通過etcdctl cluster-health查看集群狀態(tài),通過etcdctl member list查看集群節(jié)點。
如果啟動沒有報錯,添加flannel需要的配置。也就是規(guī)劃網(wǎng)段的配置。
etcdctl mk /coreos.com/network/config '{"Network":"172.17.0.0/16", "SubnetMin": "172.17.1.0", "SubnetMax": "172.17.254.0"}'
配置flannel網(wǎng)絡(luò)
配置flannel
其實flannel也是和etcd一樣,不用安裝的,直接從官方下載二進制執(zhí)行文件就可以了,當然,你也可以自己編譯
,首先配置好flannel,再配置docker,使其使用flannel網(wǎng)絡(luò)。
編輯/usr/lib/systemd/system/flanneld.service(主要修改成你的flanneld程序路徑):
[Unit]
Description=flannel
[Service]
ExecStart=/opt/flannel/flanneld \
-etcd-endpoints=http://172.16.164.5:4001 #etcd地址
[Install]
WantedBy=multi-user.target
systemctl start flanneld
正常情況下,使用ip a s flannel0可以查看到flannel的橋接網(wǎng)卡已經(jīng)起來了。
配置docker
首先生成Docker參數(shù),在flannel程序包中有腳本,執(zhí)行/opt/flannel/mk-docker-opts.sh -c,回生成docker的啟動參數(shù),默認保存到/run/docker_opts.env,也可以使用-i參數(shù),生成的樣式不一樣,正常來說,把這些參數(shù)加到Docker的啟動參數(shù)中,重啟Docker就可以了,但是方便起見,我希望這個腳本加入到Docker中,每次重啟Docker都能重新生成這個配置,避免網(wǎng)絡(luò)變化導致參數(shù)不對,所以我修改了Docekr的啟動配置:/usr/lib/systemd/system/docker.service:(如果你不是使用引入文件的方式,就把配置項加到docker啟動參數(shù)里)
[Unit]
Description=Docker Application Container Engine
Documentation=http://docs.docker.com
After=network.target
After=flanneld.service
Requires=flanneld.service
Wants=docker-storage-setup.service
[Service]
Type=notify
NotifyAccess=all
EnvironmentFile=/run/docker_opts.env #+ 引入環(huán)境變量
EnvironmentFile=-/etc/sysconfig/docker
EnvironmentFile=-/etc/sysconfig/docker-storage
EnvironmentFile=-/etc/sysconfig/docker-network
Environment=GOTRACEBACK=crash
ExecStartPre=/opt/flannel/mk-docker-opts.sh -c #+ 執(zhí)行腳本,備下次使用
ExecStart=/bin/sh -c '/usr/bin/docker daemon $OPTIONS \
$MK_DOCKER_OPTS \ #+ 我腳本中的變量名稱我改成了這個,并在腳本中加入清理這個變量,否則每次生成的配置都會疊在一起重復
$DOCKER_OPTS \
$DOCKER_STORAGE_OPTIONS \
$DOCKER_NETWORK_OPTIONS \
$ADD_REGISTRY \
$BLOCK_REGISTRY \
$INSECURE_REGISTRY \
2>&1 | /usr/bin/forward-journald -tag docker'
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
MountFlags=slave
TimeoutStartSec=0
Restart=on-failure
StandardOutput=null
StandardError=null
[Install]
WantedBy=multi-user.target
之后重啟docker,正常的話,使用ip a可以看到docker0網(wǎng)卡和flannel0網(wǎng)卡是在同一個網(wǎng)段。多個節(jié)點配置好后,不同主機上運行容器,容器之間應(yīng)該也是可以直接訪問。
到此,基礎(chǔ)環(huán)境就準備好了
安裝Kubernetes
單集群Kubernets,也不做Master HA的話,配置還是比較簡單的,但是很多用戶都反映安裝復雜,所以Kubernetes每一次版本更新,都升級更新安裝方式,單機部署、Docker部署包、多集群部署等等讓人眼花繚亂,接下來采用的是最無腦的方式,直接虛擬機部署。
安裝比較簡單,都是二進制文件,只需要放到對應(yīng)的目錄啟動即可。
首先,所有機器添加好IP變量,便于引用,在資源列表中的setup-network-environment這個工具執(zhí)行后就是會生成這個配置文件的,之后再手動加上MASTER_IP設(shè)置/etc/network-environment
如果不使用工具,自己寫上就好了。
LO_IPV4=127.0.0.1
ETH0_IPV4=172.16.164.6
DEFAULT_IPV4=172.16.164.6
DOCKER0_IPV4=172.17.67.1
FLANNEL0_IPV4=172.17.67.0
MASTER_IP=172.16.164.5
部署Master
所有服務(wù)文件在壓縮包的這個路徑kubernetes/server/kubernetes-server-linux-amd64.tar.gz,解壓出來就是可以部署的二進制文件、Docker鏡像等,這里只需要用到二進制文件,下面等服務(wù),都是只需要設(shè)置好systemd(/usr/lib/systemd/system/service-name.service)配置,啟動即可。
配置SSL(可選)
首先配置SSL證書,如果不配置的話,Kubernetes啟動的時候會自動創(chuàng)建,但是創(chuàng)建的證書當然是不會加入我們的master地址的,所以這里自己創(chuàng)建。
mkdir -p /etc/kubernetes/ssl
cd /etc/kubernetes/ssl
openssl genrsa -out ca-key.pem 2048
openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca"
vim openssl.cnf
[req]
req_extensions = v3_req
distinguished_name = req_distinguished_name
[req_distinguished_name]
[ v3_req ]
basicConstraints = CA:FALSE
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
DNS.5 = m #注意填你自己的Master 主機名
IP.1 = 10.0.0.1
IP.2 = 10.201.78.110 #注意填你自己的Master IP
openssl genrsa -out apiserver-key.pem 2048
openssl req -new -key apiserver-key.pem -out apiserver.csr -subj "/CN=kube-apiserver" -config openssl.cnf
openssl x509 -req -in apiserver.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out apiserver.pem -days 365 -extensions v3_req -extfile openssl.cnf
kube-apiserver
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
Requires=etcd.service
After=etcd.service
[Service]
EnvironmentFile=/etc/network-environment
ExecStart=/opt/bin/kube-apiserver \
--client_ca_file=/etc/kubernetes/ssl/ca.pem \
--tls-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem \
--tls-cert-file=/etc/kubernetes/ssl/apiserver.pem \
--service-account-key-file=/etc/kubernetes/ssl/apiserver-key.pem \
--service-account-lookup=false \
--admission-control=NamespaceLifecycle,NamespaceAutoProvision,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota \
--runtime-config=api/v1 \
--allow-privileged=true \
--insecure-bind-address=0.0.0.0 \
--insecure-port=8080 \
--kubelet-https=true \
--secure-port=6443 \
--service-cluster-ip-range=10.0.0.0/16 \
--etcd-servers=http://127.0.0.1:4001 \
--public-address-override=${DEFAULT_IPV4} \
--logtostderr=true \
--cors-allowed-origins='.*'
Restart=always
RestartSec=10
systemctl start kube-apiserver
kube-controller-manager
[Unit]
Description=kubernetes Controller Manager
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
Requires=kbapi.service
After=kbapi.service
[Service]
ExecStart=/opt/bin/kube-controller-manager \
--service-account-private-key-file=/etc/kubernetes/ssl/apiserver-key.pem \
--root-ca-file=/etc/kubernetes/ssl/ca.pem \
--master=127.0.0.1:8080 \
--logtostderr=true
Restart=always
RestartSec=10
systemctl start kube-controller-manager
kube-scheduler
[Unit]
Description=kubernetes Scheduler
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
Requires=kbapi.service
After=kbapi.service
[Service]
ExecStart=/opt/bin/kube-scheduler \
--master=127.0.0.1:8080
Restart=always
RestartSec=10
systemctl start kube-scheduler
kube-dns
[Unit]
Description=Kubernetes DNS Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
After=kbapi.service
Requires=kbapi.service
[Service]
ExecStart=/opt/bin/kube-dns \
--dns-port=53 \
--domain=cluster.local \
--kube-master-url=http://10.201.78.110:8080 #kube-api地址
Restart=on-failure
RestartSec=10
systemctl start kube-dns
安裝Minion
安裝方式和Master差不多,只是更加簡單,開啟兩個進程即可,同樣,記得添加好/etc/network-environment配置 。
Kubelet
[Unit]
Description=kubernetes Kubelet
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
EnvironmentFile=/etc/network-environment
ExecStart=/opt/bin/kubelet \
--address=0.0.0.0 \
--port=10250 \
--hostname-override=${DEFAULT_IPV4} \
--api-servers=${MASTER_IP}:8080 \
--allow-privileged=true \
--logtostderr=true \
--cadvisor-port=4194 \
--cluster_dns=10.201.78.110 \
--cluster_domain=cluster.local \
--healthz-bind-address=0.0.0.0 \
--healthz-port=10248
Restart=always
RestartSec=10
systemctl start Kubelet
kube-proxy
[Unit]
Description=kubernetes Proxy
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
[Service]
EnvironmentFile=/etc/network-environment
ExecStart=/opt/bin/kube-proxy \
--master=${MASTER_IP}:8080 \
--proxy-mode=iptables \
--logtostderr=true
Restart=always
RestartSec=10
systemctl start kube-proxy
結(jié)束
到此,Kubernetes的部署就結(jié)束了,通常來說,你在Master中之行kubectl get nodes就能看到集群節(jié)點就表示這個集群可用了。當然,這只是革命的開始,盡管Kubernetes解決了很多Docker引入的問題,但是如果你想要在生產(chǎn)環(huán)境中使用Kubernetes,你還要解決的問題有很多,比如性能、監(jiān)控、日志、更新等等,在之后的文章了里,再細細研究了。
支持一下咯( ??﹏??)(支付寶)
