centos安裝kubernetes,calico,nfs

kubernetes+calico+nfs環境部署

原作者 張偉@天雲軟件,轉載請註明出處


主機說明:

  • 系統版本:centos7.2,Linux kernel 3.10.0及以上版本。
  • 系統規格:>=4CPU,>=4GRAM,120G磁盤(使用lvm管理,可動態擴容)。

主機規劃:

角色 主機名 IP 說明
master,etcd master 172.16.10.2 etcd,kubernetes(apiserver,scheduler,controller-manager),calico
minion minion1 172.16.10.3 kubernetes(kubelet,proxy),docker,calico
minion minion2 172.16.10.4 kubernetes(kubelet,proxy),docker,calico
registry registry 172.16.10.5 registry
nfsserver nfsserver 172.16.10.6 nfs-server

軟件:

  • etcd v2.2.5
  • docker v1.9.1
  • kubernetes二進制包(安裝完成後可替換二進制包進行升級):
    • kubectl v1.2.0
    • kubelet v1.2.0
    • kube-proxy v1.2.0
    • kube-scheduler v1.2.0
    • kube-controller-manager v1.2.0
    • kube-apiserver v1.2.0
    • registry.access.redhat.com/rhel7/pod-infrastructure:latest(鏡像)
  • calico:
    • calicoctl v0.18.0
    • calico/node:v0.18.0 (鏡像)
    • calico v1.1.0
    • calico-ipam v1.1.0
    • calico/k8s-policy-agent:v0.1.2 (鏡像)
    • policy
  • easyrsa3

安裝kubernetes集羣

1.準備安裝源
建議使用阿里源替換系統自帶的源
配置kubernetes安裝源
關閉selinux: setenforce 0

2.安裝kubernetes master節點
yum install kubernetes etcd -y 安裝kubernetes的所有服務。

1)配置crt通信證書
1.1) 配置apiserver crt證書:
下載easyrsa3:
curl -L -O https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz
tar xzf easy-rsa.tar.gz
cd easy-rsa-master/easyrsa3
./easyrsa init-pki
創建CA:
./easyrsa --batch "--req-cn=${MASTER_IP}@`date +%s`" build-ca nopass  (如果要使用默認的service訪問kubernetes集羣,使用--req-cn=*)
生成服務使用的cert和key:
./easyrsa --subject-alt-name="IP:${MASTER_IP}" build-server-full kubernetes-master nopass(如果要使用默認的service訪問kubernetes集羣,要在IP後邊配置service的IP:IP:${MASTER_IP},IP:${SERVICE_IP})*
mkdir -p /srv/kubernetes  
cp pki/ca.crt /srv/kubernetes/
cp pki/issued/kubernetes-master.crt /srv/kubernetes/server.cert  
cp pki/issued/kubernetes-master.key /srv/kubernetes/server.key

1.2)配置ServiceAccount:
openssl genrsa -out /srv/kubernetes/serviceaccount.key 2048

chmod +x /srv/kubernetes/*

2)配置etcd服務
vi /etc/etcd/etcd.conf
修改etcd監聽的網卡和端口,使服務能夠在集羣內訪問。

systemctl enable etcd
systemctl restart etcd  

3)配置apiserver
vi /etc/kubernetes/config
將KUBE_MASTER的值修改爲正確的IP地址。
# 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=true"

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

vi /etc/kubernetes/apiserver
修改apiserver監聽的網卡和端口,並配置使用的etcd集羣。注意增加apiserver的證書設置。
# The address on the local server to listen to.
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"

# The port on the local server to listen on.
# KUBE_API_PORT="--port=8080"
KUBE_API_PORT="--insecure-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://master: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="--client-ca-file=/srv/kubernetes/ca.crt --tls-cert-file=/srv/kubernetes/server.crt --tls-private-key-file=/srv/kubernetes/server.key --service_account_key_file=/srv/kubernetes/serviceaccount.key"


4)配置controller-manager
vi /etc/kubernetes/controller-manager
增加證書設置
# Add your own!
KUBE_CONTROLLER_MANAGER_ARGS="--root-ca-file=/srv/kubernetes/ca.crt --service_account_private_key_file=/srv/kubernetes/server.key"

5)啓動master上的服務

for SERVICES in etcd kube-apiserver kube-controller-manager kube-scheduler; do 
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICES done

3.安裝kubernetes minion節點
yum install kubernetes -y

1)配置kubelet
vi /etc/kubernetes/config
將KUBE_MASTER的值修改爲正確的IP地址。
# 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=true"

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

vi /etc/kubernetes/kubelet
# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
KUBELET_ADDRESS="--address=0.0.0.0"

# 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=${YOUR_HOST_NAME}"

# location of the api-server
KUBELET_API_SERVER="--api-servers=http://master: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=""

2)配置kube-proxy
vi /etc/kuerbnetes/proxy,可以配置proxy模式
# Add your own!
KUBE_PROXY_ARGS=" --proxy-mode=iptables"

3)啓動minon上的服務
for SERVICES in kube-proxy kubelet docker; do 
    systemctl restart $SERVICES
    systemctl enable $SERVICES
    systemctl status $SERVICESdone

4.檢查kubernetes 集羣狀態
等服務啓動完成後,在master節點上檢查集羣狀況。測試環境上master上也部署了成了minion節點。

[root@master ~]# kubectl get nodes  
NAME      LABELS                           STATUS    AGE
master    kubernetes.io/hostname=master    Ready     6d
minion1   kubernetes.io/hostname=minion1   Ready     6d
minion2   kubernetes.io/hostname=minion2   Ready     6d

安裝Calico

1.節點安裝calico (使用v0.18.0版本)

wget -o /usr/bin/calicoctl https://github.com/projectcalico/calico-containers/releases/download/v0.18.0/calicoctl  
chmod +x /usr/bin/calicoctl  

創建文件/etc/systemd/calico-node,設置etcd集羣服務地址:

[Unit]  
Description=calicoctl node  
After=docker.service  
Requires=docker.service  
[Service]     
User=root
Environment=ETCD_AUTHORITY=master:4001
PermissionsStartOnly=true
ExecStart=/usr/bin/calicoctl node --detach=false
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target

將calico-node配置成開機啓動服務,並啓動。
在環境變量中增加ETCD_AUTHORITY=master:4001的配置

systemctl enable /etc/systemd/calico-node.service
service calico-node restart  

將會使用鏡像calico/node:v0.18.0,啓動服務。

2.在所有minion節點上,安裝calico-cni擴展

wget -N -P /opt/cni/bin https://github.com/projectcalico/calico-cni/releases/download/v1.1.0/calico chmod +x /opt/cni/bin/calico
wget -N -P /opt/cni/bin https://github.com/projectcalico/calico-cni/releases/download/v1.1.0/calico-ipam
chmod +x /opt/cni/bin/calico-ipam  

配置cni網絡聲明:

$ cat /etc/cni/net.d/10-calico.conf
{
    "name" : "calico-k8s-network",
    "type" : "calico",
    "etcd_authority" : "master:4001",
    "log_level" : "info",
    "ipam" : {
        "type" : "calico-ipam"
    }
}

如果是在阿里雲上部署,需要設置calico使用ipip,用如下命令查看:

calicoctl pool show --ipv4

如果顯示

+----------------+-------------------+
|   IPv4 CIDR    |      Options      |
+----------------+-------------------+
| 192.168.0.0/16 | ipip,nat-outgoing |
+----------------+-------------------+

表示已啓用ipip,否則根據提示刪除ip池,重新添加並使用選項–ipip –nat-outgoing。

查看默認規則是否正確:

calicoctl profile calico-k8s-network rule show

如果顯示

Inbound rules:
    1 allow
Outbound rules:
    1 allow

表示默認規則正確。

驗證網絡環境是否滿足kubernetes需求:
1) 創建一個rc,副本數量和集羣的minion節點一致。
2) 測試主機到pod通信:主機 ping 本機PodIp, 主機ping 其它主機PodIp。Pod內部ping宿主機Ip,Pod內部ping其它主機Ip。
3) 測試cluster ip通信:創建service,後端使用可用的Pod服務。在Pod所在minion,使用serviceIp+port訪問服務。在其它minion,使用serviceIp+port訪問服務。
4) 測試nodePort通信:使用minion本機IP+nodeport訪問服務。使用其它minion ip+nodeport訪問服務。
如果以上測試全部通過,則網絡配置正確,否則需要排查問題。
如果排查後配置全部正確,但是kubermetes網絡某些環節不通,可以在所有節點執行:

calicoctl node

命令,重新初始化calico網絡的鏈接。

3.部署policy-agent
使用下面的yaml文件部署policy-agent,其機制爲監聽kubernetes 中pod和namespace的變化,namespace中network policy的配置變化,有policy-agent寫入到calico的etcd存儲中,然後直接由每個節點上的felix轉換爲iptables規則。

apiVersion: v1
kind: Namespace
metadata:
  name: calico-system
---
apiVersion: v1
kind: ReplicationController
metadata:
  name: calico-policy-agent
  namespace: calico-system
  labels:
    version: v0.1.2
    projectcalico.org/app: "policy-agent"
spec:
  replicas: 2
  selector:
    version: v0.1.2
    projectcalico.org/app: "policy-agent"
  template:
    metadata:
      labels:
        version: v0.1.2
        projectcalico.org/app: "policy-agent"
    spec:
      containers:
        - name: policyagent
          image: 172.16.10.5:5000/calico/k8s-policy-agent:v0.1.2
          imagePullPolicy: IfNotPresent
          env:
          - name: ETCD_ENDPOINTS
            value: "http://172.16.10.2:2379"  

部署完成後,等待服務啓動。文件中的env是讓pod使用環境變量方式訪問ETCD,如果kubernetes集羣中安裝了DNS,可以刪掉環境變量的設置,使用dns訪問ETCD服務。
在master節點上,policy用於操作network policy對象實現網絡隔離的動態控制。

wget https://github.com/projectcalico/k8s-policy/releases/download/v0.1.1/policy
chmod +x ./policy

4.修改kubernetes配置
設置kube-proxy服務的proxy-mode配置爲iptables,修改配置文件/etc/kubernetes/proxy:

###
# kubernetes proxy config
# default config should be adequate
# Add your own!
KUBE_PROXY_ARGS=" --proxy-mode=iptables"

設置kubelet的network-plugin爲cni,修改配置文件/usr/lib/systemd/system/kubelet.service:

[Unit]
Description=Kubernetes Kubelet Server
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 \
--network-plugin-dir=/etc/cni/net.d \
--network-plugin=cni \
$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
[Install]
WantedBy=multi-user.target

重啓相關服務:

service kubelet restart
service kube-proxy restart

安裝nfs服務

1.安裝nfs相關服務

yum install nfs-server  
yum install nfs  
yum install rpcbind nfs-utils

2.添加共享目錄

/share *(rw,insecure,sync,no_subtree_check,no_root_squash)
/mysql *(rw,insecure,sync,no_subtree_check,no_root_squash)

上述共享目錄的配置一定要寫上,否則在使用過程中可能出現Operation not permitted錯誤。

3.所有kubernetes minion節點安裝nfs工具

yum install rpcbind nfs-utils
  • 整體測試

常見問題及解決方案

1.kubernetes dns服務異常

首先查看kubelet是否配置正確,安裝dns需要在所有節點的kubelet啓動參數中增加

--cluster-dns=10.254.0.3 --cluster-domain=cluster.local

參數。

其次查看dns版本,確定kube2sky和kubernetes api通信的方式,老版本的(如v9版本),需要在yaml文件中指定kubernetes apiserver的地址和端口。新版本的(如v11版本),使用kubernetes默認的kubernetes service訪問kubernetes。如果是新版本,請參考 配置crt通信證書 一節,修改crt證書生成方式。 如果是老版本,確定kubernetes的網絡是否配置正確。

2.pv和pvc綁定失敗
pv和pvc匹配要檢查以下幾點:
1) pv和pvc的標籤是否一致。
2) pv和pvc的大小是否滿足要求,pvc的容量要求不能大於pv的容量。
3) pv和pvc的accessModes必須相同。

3.mysql容器使用nfs啓動不了
查看mysql對應Pod的日誌,如果出現Operation not permitted錯誤,是因爲nfs設置的共享目錄權限不足,在共享目錄設置中增加no_root_squash設置。

4.kubernetes https訪問權限問題
訪問Pod中服務可能會報以下錯誤:

x509: cannot validate certificate for x.x.x.x because it doesn't contain any IP SANs

這個是因爲沒有設置或者設置的證書出錯,參考 配置crt通信證書 重新生成證書,修改配置即可。

5.guestbook服務寫數據無響應
這個是因爲guestbook要使用的angular.min.js需要翻牆才能使用,可以把js文件下載到本地,重新生成鏡像。

6.cassandra服務無法訪問kubernetes api
v6版本的cassandra使用的SeedProvider有BUG,使用的默認的服務域名爲

kubernetes.default.cluster.local

正確的應該是

kubernetes.default.svc.cluster.local

這個只能通過重新編譯源碼,打包鏡像解決。
v7版本的鏡像因權限問題cassandra啓動腳本執行失敗。沒有深入研究解決方法。
v8版本已經解決了上述問題,但是沒有找到可以使用的鏡像。

7.nslookup解析正常,不能用域名訪問服務
查看主機的/etc/resolv.conf文件,如果存在類似記錄則刪除掉:

options timeout:1 attempts:1 rotate

8.問題排查方法
1) kubectl describe pod POD_NAME –namespace=NAME_SPACE查看Pod的事件及基本信息。如下載鏡像失敗等問題都可以從這塊定位出來。
2) kubectl logs POD_NAME –namespace=NAME_SPACE查看Pod的日誌,定位服務本身的問題,具體問題具體分析。
3) 在Pod內部訪問kubernetes apiserver有兩種方式。
一種是指定apiserver的地址和端口,如果使用這種方式訪問失敗,比如timeout,可以從集羣網絡環境入手排查問題。
另一種是使用kubernetes的默認service訪問,這種訪問方式使用的是https,並且依賴於集羣dns服務。如果出現問題,先排查集羣的dns服務是否安裝正確。創建busybox Pod,執行

kubectl exec busybox nslookup kubernetes.default.svc.cluster.local --namespace=kube-system

Server:    10.254.0.3
Address 1: 10.254.0.3

Name:      kubernetes.default.svc.cluster.local
Address 1: 10.254.0.1

如果可以正確解析域名說明服務正常。

其次排查集羣crt證書是否配置正確。使用命令:

kubectl exec frontend-0ghx0 ls /var/run/secrets/kubernetes.io/serviceaccount/

查看Pod內部證書和crt文件。

9.kubernetes升級
centos源安裝的kubernetes有很多問題,可以使用官方release的版本升級kubernetes。升級方式是下載二進制包,停止kubernetes服務,用下載的二進制包替換老的二進制包,重新啓動服務即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章