天天看點

kubernetes 叢集的安裝部署

本文來自我的github pages部落格http://galengao.github.io/ 即www.gaohuirong.cn

摘要:

  • 首先kubernetes得官方文檔我自己看着很亂,資訊很少,是以結合了很多部落格搭建的
  • 其次因為既然用到docker,當然離不開kubernetes管理,還有swarm,前者管理複雜,但功能齊全
  • 這裡僅僅是安裝部署,還未使用,具體使用出現問題後續更新

前提條件

系統時centos7上 關閉防火牆 systemctl stop firewalld.service 關閉selinux vi /etc/selinux/comfig

主要元件說明

Kubernetes 叢集中主要存在兩種類型的節點,分别是 master 節點,以及 minion 節點。

Minion 節點是實際運作 Docker 容器的節點,負責和節點上運作的 Docker 進行互動,并且提供了代理功能。

Master 節點負責對外提供一系列管理叢集的 API 接口,并且通過和 Minion 節點互動來實作對叢集的操作管理。

apiserver:使用者和 kubernetes 叢集互動的入口,封裝了核心對象的增删改查操作,提供了 RESTFul 風格的 API 接口,通過 etcd 來實作持久化并維護對象的一緻性。

scheduler:負責叢集資源的排程和管理,例如當有 pod 異常退出需要重新配置設定機器時,scheduler 通過一定的排程算法進而找到最合适的節點。

controller-manager:主要是用于保證 replicationController 定義的複制數量和實際運作的 pod 數量一緻,另外還保證了從 service 到 pod 的映射關系總是最新的。

kubelet:運作在 minion 節點,負責和節點上的 Docker 互動,例如啟停容器,監控運作狀态等。

proxy:運作在 minion 節點,負責為 pod 提供代理功能,會定期從 etcd 擷取 service 資訊,并根據 service 資訊通過修改 iptables 來實作流量轉發(最初的版本是直接通過程式提供轉發功能,效率較低。),将流量轉發到要通路的 pod 所在的節點上去。

etcd:key-value鍵值存儲資料庫,用來存儲kubernetes的資訊的。

flannel:Flannel 是 CoreOS 團隊針對 Kubernetes 設計的一個覆寫網絡(Overlay Network)工具,需要另外下載下傳部署。我們知道當我們啟動 Docker 後會有一個用于和容器進行互動的 IP 位址,如果不去管理的話可能這個 IP 位址在各個機器上是一樣的,并且僅限于在本機上進行通信,無法通路到其他機器上的 Docker 容器。Flannel 的目的就是為叢集中的所有節點重新規劃 IP 位址的使用規則,進而使得不同節點上的容器能夠獲得同屬一個内網且不重複的 IP 位址,并讓屬于不同節點上的容器能夠直接通過内網 IP 通信。

部署規劃

這裡我用3台伺服器搭建一個簡單的叢集:

192.168.10.147 # master節點(etcd,kubernetes-master)

192.168.10.148 # node節點(etcd,kubernetes-node,docker,flannel)

192.168.10.149 # node節點(etcd,kubernetes-node,docker,flannel)

由于kubernetes的程序較多,每個節點上的程序如圖:

安裝

  • 1、分别先在兩個node上安裝docker

安裝方式參照我的另一篇文章docker安裝

yum update

tee /etc/yum.repos.d/docker.repo <<EOF
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

yum install docker-engine      
  • 2、在master安裝
yum install kubernetes-master etcd -y      
  • 3、分别在兩個node上安裝
yum install kubernetes-node etcd flannel -y      
  • 4、etcd叢集配置

在master節點上編輯etcd配置檔案

vi /etc/etcd/etcd.conf

# [member]
ETCD_NAME=etcd1
ETCD_DATA_DIR="/var/lib/etcd/etcd1.etcd"
#ETCD_WAL_DIR=""
#ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
ETCD_LISTEN_PEER_URLS="http://192.168.10.147:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.10.147:2379,http://127.0.0.1:2379"
CD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
#
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.10.147:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
ETCD_INITIAL_CLUSTER="etcd1=http://192.168.10.147:2380,etcd2=http://192.168.10.148:2380,etcd3=http://192.168.10.149:2380"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.10.147:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#
#[proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#
#[logging]
#ETCD_DEBUG="false"
# examples for -log-package-levels etcdserver=WARNING,security=DEBUG
#ETCD_LOG_PACKAGE_LEVELS=""      

在node1上編輯配置檔案

vi /etc/etcd/etcd.conf

# [member]
ETCD_NAME=etcd2
ETCD_DATA_DIR="/var/lib/etcd/etcd2"
#ETCD_WAL_DIR=""
#ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
ETCD_LISTEN_PEER_URLS="http://192.168.10.148:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.10.148:2379,http://127.0.0.1:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
#
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.10.148:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
ETCD_INITIAL_CLUSTER="etcd1=http://192.168.10.147:2380,etcd2=http://192.168.10.148:2380,etcd3=http://192.168.10.149:2380"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.10.148:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#
#[proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#
#[logging]
#ETCD_DEBUG="false"
# examples for -log-package-levels etcdserver=WARNING,security=DEBUG
#ETCD_LOG_PACKAGE_LEVELS=""      

在node2上編輯配置檔案

vi /etc/etcd/etcd.conf

# [member]
ETCD_NAME=etcd3
ETCD_DATA_DIR="/var/lib/etcd/etcd3"
#ETCD_WAL_DIR=""
#ETCD_SNAPSHOT_COUNT="10000"
#ETCD_HEARTBEAT_INTERVAL="100"
#ETCD_ELECTION_TIMEOUT="1000"
ETCD_LISTEN_PEER_URLS="http://192.168.10.149:2380"
ETCD_LISTEN_CLIENT_URLS="http://192.168.10.149:2379,http://127.0.0.1:2379"
#ETCD_MAX_SNAPSHOTS="5"
#ETCD_MAX_WALS="5"
#ETCD_CORS=""
#
#[cluster]
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://192.168.10.149:2380"
# if you use different ETCD_NAME (e.g. test), set ETCD_INITIAL_CLUSTER value for this name, i.e. "test=http://..."
ETCD_INITIAL_CLUSTER="etcd1=http://192.168.10.147:2380,etcd2=http://192.168.10.148:2380,etcd3=http://192.168.10.149:2380"
#ETCD_INITIAL_CLUSTER_STATE="new"
#ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_ADVERTISE_CLIENT_URLS="http://192.168.10.149:2379"
#ETCD_DISCOVERY=""
#ETCD_DISCOVERY_SRV=""
#ETCD_DISCOVERY_FALLBACK="proxy"
#ETCD_DISCOVERY_PROXY=""
#
#[proxy]
#ETCD_PROXY="off"
#ETCD_PROXY_FAILURE_WAIT="5000"
#ETCD_PROXY_REFRESH_INTERVAL="30000"
#ETCD_PROXY_DIAL_TIMEOUT="1000"
#ETCD_PROXY_WRITE_TIMEOUT="5000"
#ETCD_PROXY_READ_TIMEOUT="0"
#
#[security]
#ETCD_CERT_FILE=""
#ETCD_KEY_FILE=""
#ETCD_CLIENT_CERT_AUTH="false"
#ETCD_TRUSTED_CA_FILE=""
#ETCD_PEER_CERT_FILE=""
#ETCD_PEER_KEY_FILE=""
#ETCD_PEER_CLIENT_CERT_AUTH="false"
#ETCD_PEER_TRUSTED_CA_FILE=""
#
#[logging]
#ETCD_DEBUG="false"
# examples for -log-package-levels etcdserver=WARNING,security=DEBUG
#ETCD_LOG_PACKAGE_LEVELS=""      

針對幾個URLS做下簡單的解釋:

[member]

ETCD_NAME :ETCD的節點名

ETCD_DATA_DIR:ETCD的資料存儲目錄

ETCD_SNAPSHOT_COUNTER:多少次的事務送出将觸發一次快照

ETCD_HEARTBEAT_INTERVAL:ETCD節點之間心跳傳輸的間隔,機關毫秒

ETCD_ELECTION_TIMEOUT:該節點參與選舉的最大逾時時間,機關毫秒

ETCD_LISTEN_PEER_URLS:該節點與其他節點通信時所監聽的位址清單,多個位址使用逗号隔開,其格式可以劃分為scheme://IP:PORT,這裡的scheme可以是http、https

ETCD_LISTEN_CLIENT_URLS:該節點與用戶端通信時監聽的位址清單

[cluster]

ETCD_INITIAL_ADVERTISE_PEER_URLS:該成員節點在整個叢集中的通信位址清單,這個位址用來傳輸叢集資料的位址。是以這個位址必須是可以連接配接叢集中所有的成員的。

ETCD_INITIAL_CLUSTER:配置叢集内部所有成員位址,其格式為:ETCD_NAME=ETCD_INITIAL_ADVERTISE_PEER_URLS,如果有多個使用逗号隔開

ETCD_ADVERTISE_CLIENT_URLS:廣播給叢集中其他成員自己的用戶端位址清單

至此etcd叢集就部署完了,然後每個節點上啟動

systemctl start kube-apiserver      
驗證:      
[root@k8s1 ~]# etcdctl cluster-health
member 35300bfb5308e02c is healthy: got healthy result from http://192.168.10.147:2379
member 776c306b60e6f972 is healthy: got healthy result from http://192.168.10.149:2379
member a40f86f061be3fbe is healthy: got healthy result from http://192.168.10.148:2379      
  • 5、kubernetes master安裝

修改apiserver配置檔案

[root@k8s1 ~]# vi /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="--insecure-bind-address=127.0.0.1"
KUBE_API_ADDRESS="--address=0.0.0.0"

# 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://192.168.10.147:2379,http://192.168.10.148:2379,http://192.168.10.149:2379"

# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"

# default admission control policies
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"

# Add your own!
KUBE_API_ARGS=""      

配置controller-manager 暫時不做修改

[root@k8s1 etcd]# vi /etc/kubernetes/controller-manager 
###
# The following values are used to configure the kubernetes controller-manager

# defaults from config and apiserver should be adequate

# Add your own!
KUBE_CONTROLLER_MANAGER_ARGS=""      

啟動Master上的三個服務

systemctl start kube-apiserver
systemctl start kube-controller-manager
systemctl start kube-scheduler
systemctl enable kube-apiserver
systemctl enable kube-controller-manager
systemctl enable kube-scheduler      
  • 6、kubernetes node安裝部署

修改節點config配置檔案

[root@k8s1 ~]# vi /etc/kubernetes/config 
###
# kubernetes system config
#
# The following values are used to configure various aspects of all
# kubernetes services, including
#
#   kube-apiserver.service
#   kube-controller-manager.service
#   kube-scheduler.service
#   kubelet.service
#   kube-proxy.service
# logging to stderr means we get it in the systemd journal
KUBE_LOGTOSTDERR="--logtostderr=true"

# journal message level, 0 is debug
KUBE_LOG_LEVEL="--v=0"

# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow-privileged=false"

# How the controller-manager, scheduler, and proxy find the apiserver
KUBE_MASTER="--master=http://192.168.10.147:8080"
~      

修改kubelet配置

[root@k8s1 ~]# vi /etc/kubernetes/kubelet 
###
# kubernetes kubelet (minion) config

# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=127.0.0.1"

# The port for the info server to serve on
# KUBELET_PORT="--port=10250"

# You may leave this blank to use the actual hostname
KUBELET_HOSTNAME="--hostname-override=192.168.10.148"

# location of the api-server
KUBELET_API_SERVER="--api-servers=http://192.168.10.147:8080"

# pod infrastructure container
KUBELET_POD_INFRA_CONTAINER="--pod-infra-container-image=registry.access.redhat.com/rhel7/pod-infrastructure:latest"

# Add your own!
KUBELET_ARGS=""      

分别啟動kubernetes node服務

systemctl start kubelet
systemctl start kube-proxy
systemctl enable kubelet
systemctl enable kube-proxy      

網絡配置

這裡網絡部分是以插件的形式配置在kubernetes叢集中,這裡選用flannel。

  • 1、安裝flannel

上述步驟已經在node上安裝

yum install flannel -y

  • 2、配置flannel
[root@k8s1 ~]# vi /etc/sysconfig/flanneld 

FLANNEL_ETCD_KEY="/atomic.io
# Flanneld configuration options

# etcd url location.  Point this to the server where etcd runs
FLANNEL_ETCD="http://192.168.10.147:2379"

# etcd config key.  This is the configuration key that flannel queries
# For address range assignment
FLANNEL_ETCD_KEY="/coreos.com/network"

# Any additional options that you want to pass
#FLANNEL_OPTIONS=""      
  • 3、為flannel建立配置設定的網絡
# 隻在master上etcd執行
etcdctl mk /coreos.com/network/config '{"Network": "10.1.0.0/16"}'
# 若要重建立,先删除
etcdctl rm /coreos.com/network/ --recursive      

重置docker0網橋的配置

删除docker啟動時預設建立的docker0網橋,flannel啟動時會擷取到一個網絡位址,并且配置docker0的IP位址,作為該網絡的網關位址,如果此時docker0上配置有IP位址,那麼flannel将會啟動失敗。

ip link del docker0

檢查

在master上執行下面,檢查kubernetes的狀态

[root@k8s1 ~]# kubectl get nodes
NAME             STATUS    AGE
192.168.10.148   Ready     3h
192.168.10.149   Ready     3h      

在master上執行下面,檢查etcd的狀态

[root@k8s1 ~]# etcdctl  member list
35300bfb5308e02c: name=etcd1 peerURLs=http://192.168.10.147:2380 clientURLs=http://192.168.10.147:2379
776c306b60e6f972: name=etcd3 peerURLs=http://192.168.10.149:2380 clientURLs=http://192.168.10.149:2379
a40f86f061be3fbe: name=etcd2 peerURLs=http://192.168.10.148:2380 clientURLs=http://192.168.10.148:2379      
centos7檢視日志指令: journalctl -xe 或者 systemctl status flanneld.service flanneld對應改成你的項目