1. 程式人生 > >Kuberbetes1.10 集群部署

Kuberbetes1.10 集群部署

k8s

部署說明

此篇文章介紹的是Kubernets的1.10.2版本使用kubeadm 工具自動化部署一套簡單的k8s集群,不涉及具體原理的說明。在後續的更新中會逐步加入一些常見的生產應用案例。

環境準備

Master: 10.0.0.1 node-1

node: 10.0.0.2 node-2

所有節點初始化

1、所有節點安裝docker,官方推薦docker 1.12的版本,使用 v1.11, v1.13 和v17.03的也可以,不要使用最新的版本。

yum install -y docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch.rpm 
yum install -y docker-ce-17.03.2.ce-1.el7.centos.x86_64.rpm 

2、配置國內鏡像源:

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

3、安裝所需組件

setenforce 0
yum install -y kubelet kubeadm kubectl
systemctl enable docker && systemctl start docker
systemctl enable kubelet && systemctl start kubelet

4、查看docker 使用的Cgroup driver 和 k8s的是否一致,如果不一致需要修改:

docker info | grep -i cgroup
cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf|grep "cgroup-driver"
 #不一致的情況下需要修改:
sed -i "s/cgroup-driver=systemd/cgroup-driver=cgroupfs/g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

5、修改系統配置,防止iptable報錯:

cat <<EOF >  /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sysctl --system

6、重啟kubelet:

systemctl daemon-reload
systemctl restart kubelet

7、在docker 的啟動文件中,加入國內的鏡像加速,重啟docker:

vim /usr/lib/systemd/system/docker.service
...
ExecStart=/usr/bin/dockerd --registry-mirror https://qxx96o44.mirror.aliyuncs.com
...
systemctl daemon-reload
systemctl restart docker

8、設置主機名並解析,同步系統時間。

ntpdate times.aliyun.com

安裝Master

初始化Master

在此處下載docker鏡像: https://hub.docker.com/r/anjia0532/

1、使用如下腳本,下載鏡像,並修改為google的源,否則容器無法啟動:

#!/bin/bash
images=(kube-proxy-amd64:v1.10.2 kube-scheduler-amd64:v1.10.2 kube-controller-manager-amd64:v1.10.2 kube-apiserver-amd64:v1.10.2
etcd-amd64:3.1.12 pause-amd64:3.1 kubernetes-dashboard-amd64:v1.8.3 k8s-dns-sidecar-amd64:1.14.8 k8s-dns-kube-dns-amd64:1.14.8
k8s-dns-dnsmasq-nanny-amd64:1.14.8)
for imageName in ${images[@]} ; do
  docker pull anjia0532/$imageName
  docker tag anjia0532/$imageName k8s.gcr.io/$imageName
  docker rmi anjia0532/$imageName
done

執行此腳本,完成鏡像的下載。

2、使用kubeadm init自動安裝 Master 節點,需要指定版本:

kubeadm init  --kubernetes-version=v1.10.2    # 使用weave 等網絡以這種方式初始化

kubeadm init --kubernetes-version=v1.10.2  --pod-network-cidr=10.244.0.0/16    # 使用flannel 網絡需要加 --pod-network-cidr 參數

提示:在執行此命令的過程中,可以實時查看/var/log/message中的日誌,確認服務是否啟動,要特別註意鏡像的版本,名稱一致性問題,輸出成功的記錄需要保留,後面還會用到。

3、服務啟動後需要根據輸出提示,進行配置,如果是非root 用戶需要執行:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

# 如果是root 用戶執行的初始化,則已經創建了此文件, 只需執行:
export KUBECONFIG=/etc/kubernetes/admin.conf

配置網絡

提示:我們需要安裝網絡插件才能使pod之間進行通信,網絡插件的安裝必須在應用部署之前。同時,在啟動kube-dns和內部輔助服務之前必須先配置好網絡。

K8S支持多種網絡插件,下面是對常見幾種插件的簡單介紹:

  • ACI通過思科ACI提供集成的集裝箱網絡和網絡安全。
  • Calico是一個安全的L3網絡和網絡策略提供者。
  • Canal 結合Flannel和Calico,提供網絡和網絡策略。
  • Cilium是L3網絡和網絡策略插件,可以透明地實施HTTP / API / L7策略。支持路由和覆蓋/封裝模式
  • CNI-Genie使Kubernetes能夠無縫地連接到一系列CNI插件,例如Calico,Canal,Flannel,Romana或Weave。
  • Contiv為各種用例和豐富的策略框架提供了可配置的網絡(使用BGP的本地L3,使用vxlan的覆蓋,傳統L2和Cisco-SDN / ACI)。 Contiv項目完全開源。安裝程序提供基於kubeadm和非kubeadm的安裝選項。
  • Flannel 提供一種覆蓋網絡,可以與Kubernetes一起使用。
  • Multus 提供除Kubernetes中的SRIOV,DPDK,OVS-DPDK和VPP工作負載之外,還是一個多插件,用於支持Kubernetes中的多個網絡,以支持所有CNI插件(例如Calico,Cilium,Contiv,Flannel)。
  • NSX-T容器插件(NCP)提供VMware NSX-T與Kubernetes等容器編排器之間的集成,以及NSX-T與基於容器的CaaS / PaaS平臺(如Pivotal Container Service(PKS)和Openshift 。
  • Nuage是一個SDN平臺,可以在Kubernetes Pod和非Kubernetes環境之間提供基於策略的網絡,並提供可視性和安全監控。
  • Romana是一種用於pod網絡的第3層網絡解決方案,也支持NetworkPolicy API。 Kubeadm附加安裝細節可在此處獲得。
  • Weave提供網絡和網絡策略,將在網絡分區的兩側進行工作,並且不需要外部數據庫

這裏我們選擇使用 flannel網絡。

1、在Master上執行如下命令,完成網絡安裝:

sysctl net.bridge.bridge-nf-call-iptables=1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml

## weave 網絡使用如下命令,有興趣的同學可以嘗試?
sysctl net.bridge.bridge-nf-call-iptables=1
kubectl apply -f "https://cloud.weave.works/k8s/net?k8s-version=$(kubectl version | base64 | tr -d ‘\n‘)"

2、驗證是否正常啟動。

[root@node-1 ~]# kubectl get pods --all-namespaces
NAMESPACE     NAME                             READY     STATUS    RESTARTS   AGE
kube-system   etcd-node-1                      1/1       Running   0          9m
kube-system   kube-apiserver-node-1            1/1       Running   0          9m
kube-system   kube-controller-manager-node-1   1/1       Running   0          9m
kube-system   kube-dns-86f4d74b45-jjc42        3/3       Running   0          10m
kube-system   kube-flannel-ds-hfv57            1/1       Running   0          9m
kube-system   kube-proxy-wsmxl                 1/1       Running   0          10m
kube-system   kube-scheduler-node-1            1/1       Running   0          9m

端口信息:

[root@node-1 ~]# netstat -lntpu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:10248         0.0.0.0:*               LISTEN      9321/kubelet        
tcp        0      0 127.0.0.1:10249         0.0.0.0:*               LISTEN      9751/kube-proxy     
tcp        0      0 127.0.0.1:10251         0.0.0.0:*               LISTEN      9575/kube-scheduler 
tcp        0      0 127.0.0.1:2379          0.0.0.0:*               LISTEN      9521/etcd           
tcp        0      0 127.0.0.1:10252         0.0.0.0:*               LISTEN      9583/kube-controlle 
tcp        0      0 127.0.0.1:2380          0.0.0.0:*               LISTEN      9521/etcd           
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      963/sshd            
tcp6       0      0 :::10250                :::*                    LISTEN      9321/kubelet        
tcp6       0      0 :::6443                 :::*                    LISTEN      9590/kube-apiserver 
tcp6       0      0 :::10255                :::*                    LISTEN      9321/kubelet        
tcp6       0      0 :::10256                :::*                    LISTEN      9751/kube-proxy     
tcp6       0      0 :::22                   :::*                    LISTEN      963/sshd            
udp        0      0 0.0.0.0:8472            0.0.0.0:*                           -                 

提示:如果執行此命令出現x509的認證失敗錯誤,請確認當前的命令行窗口已經export admin.conf的環境變量。

故障排查思路:

  • 確認端口和容器是否正常啟動,查看 /var/log/message日誌信息
  • 通過docker logs ID 查看容器的啟動日誌,特別是頻繁創建的容器
  • 使用kubectl --namespace=kube-system describe pod POD-NAME 查看錯誤狀態的pod日誌。
  • 使用kubectl -n ${NAMESPACE} logs ${POD_NAME} -c ${CONTAINER_NAME} 查看具體錯誤。
  • Calico - Canal - Flannel已經被官方驗證過,其他的網絡插件有可能有坑,能不能爬出來就看個人能力了。
  • 一般常見的錯誤是鏡像名稱版本不對或者鏡像無法下載。

添加節點

1、在需要添加的節點上執行:

docker pull mirrorgooglecontainers/pause-amd64:3.1
docker pull mirrorgooglecontainers/kube-proxy-amd64:v1.10.2
docker tag mirrorgooglecontainers/pause-amd64:3.1 k8s.gcr.io/pause-amd64:3.1
docker tag mirrorgooglecontainers/kube-proxy-amd64:v1.10.2 k8s.gcr.io/kube-proxy-amd64:v1.10.2

sysctl net.bridge.bridge-nf-call-iptables=1
# 此行命令來源於初始化Master成功後的輸出
kubeadm join 10.0.0.1:6443 --token h00k39.t6l79i7cbm79n4gy --discovery-token-ca-cert-hash sha256:205922c8412e5a3ea1616c060c79c9b6b38d098833f46d261fdf5ed1ca7e3027

2、執行添加命令後,在Master上查看節點信息:

[root@node-1 ~]# kubectl get nodes
NAME      STATUS    ROLES     AGE       VERSION
node-1    Ready     master    1h        v1.10.2
node-2    Ready     <none>    23m       v1.10.2

3、查看端口信息:

[root@node-2 ~]# netstat -lntpu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:10248         0.0.0.0:*               LISTEN      24246/kubelet       
tcp        0      0 127.0.0.1:10249         0.0.0.0:*               LISTEN      25289/kube-proxy    
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      966/sshd            
tcp6       0      0 :::10250                :::*                    LISTEN      24246/kubelet       
tcp6       0      0 :::10255                :::*                    LISTEN      24246/kubelet       
tcp6       0      0 :::10256                :::*                    LISTEN      25289/kube-proxy    
tcp6       0      0 :::22                   :::*                    LISTEN      966/sshd            
udp        0      0 0.0.0.0:8472            0.0.0.0:*                           -                

4、配置node節點,查看kubete信息:

[root@node-1 ~]# scp /etc/kubernetes/admin.conf  10.0.0.2:/etc/kubernetes/

[root@node-2 ~]# kubectl --kubeconfig /etc/kubernetes/admin.conf get nodes
NAME      STATUS    ROLES     AGE       VERSION
node-1    Ready     master    1h        v1.10.2
node-2    Ready     <none>    40m       v1.10.2

5、安照這種方式,我們可以橫向添加多個節點。

創建應用

這裏使用mysql 和tomcat 作為示例。

創建mysql的應用

1、創建一個mysql.yaml的文件:

apiVersion: v1
kind: ReplicationController         # 指定kind類型為RC
metadata:
  name: mysql                            # RC的名稱,全局唯一 
spec:
  replicas: 1                                # pod 副本數量
  selector:
    app: mysql                             # 符合目標的Pod擁有此標簽
  template:                                 # 根據此模板,創建Pod的副本(實例)
    metadata:
      labels:
        app: mysql                        # Pod 副本擁有的標簽,對應RC的Selector
    spec:
      containers:                          # Pod 內 容器定義的部分
      - name: mysql                    #  容器名稱
        image: mysql                   # 容器鏡像
        ports:
        - containerPort: 3306       # 容器應用監聽的端口
        env:                                  # 註入容器的環境變量
        - name: MYSQL_ROOT_PASSWORD
          value: "123456"

2、使用kubectl 命令發布到k8s集群,在Master執行:

 kubectl create -f mysql.yaml

3、查看容器,RC和pod狀態:

# node-2節點上創建了兩個容器,一個mysql 和 pause
[root@node-2 ~]# docker ps | grep mysql
f951c5e1043f        mysql@sha256:d60c13a2bfdbbeb9cf1c84fd3cb0a1577b2bbaeec11e44bf345f4da90586e9e1   "docker-entrypoint..."   19 minutes ago           Up 19 minutes                               k8s_mysql_mysql-kfkdd_default_6b18de55-5b14-11e8-9cc0-000c29c83e1f_0
dd17c26dad8c        k8s.gcr.io/pause-amd64:3.1                                                      "/pause"                 20 minutes ago           Up 20 minutes                               k8s_POD_mysql-kfkdd_default_6b18de55-5b14-11e8-9cc0-000c29c83e1f_0

# 查看 RC,Master上執行
[root@node-1 ~]# kubectl get rc
NAME      DESIRED   CURRENT   READY     AGE
mysql     1         1         1         22m

# 查看pod
[root@node-1 ~]# kubectl get pods
NAME          READY     STATUS    RESTARTS   AGE
mysql-kfkdd   1/1       Running   0          22m

4、創建service, 定義個mysql-service.yaml的文件:

apiVersion: v1
kind: Service                       # 說明這是一個K8S Service
metadata: 
  name: mysql                     # Service 的全局唯一名稱
spec:
  ports:
    - port: 3306                     # service 提供的服務端口號
  selector:                            # 定義有哪些pod 對應到此服務 
    app: mysql

5、創建service:

[root@node-1 ~]# kubectl create -f mysql-service.yaml 
service "mysql" created

6、查看service,這裏自動分配了一個ip和pod 中的虛端口。由於Kubernetes是使用kubeadm 以容器的方式啟動,所以有一個kubernetes的服務。

[root@node-1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP    18h
mysql        ClusterIP   10.110.213.104   <none>        3306/TCP   17s

創建tomcat 應用

1、創建rc 文件tomcat.yaml:

apiVersion: v1
kind: ReplicationController
metadata:
  name: myweb
spec:
  replicas: 2                        # 指定兩個副本
  selector:
    app: myweb
  template:
    metadata:
      labels:
        app: myweb
    spec:
      containers:
        - name: myweb
          image: kubeguide/tomcat-app:v1   
          ports:
          - containerPort: 8080

2、創建RC,並驗證:

[root@node-1 ~]# kubectl create -f tomcat.yaml 
replicationcontroller "myweb" created

[root@node-1 ~]# kubectl get rc
NAME      DESIRED   CURRENT   READY     AGE
mysql     1         1         1         1h
myweb     2         2         2         8m

[root@node-1 ~]# kubectl get pods
NAME          READY     STATUS    RESTARTS   AGE
mysql-kfkdd   1/1       Running   0          1h
myweb-qqmp8   1/1       Running   0          7m
myweb-sz64h   1/1       Running   0          7m

[root@node-2 ~]# docker ps|grep myweb
c98ce89ce2c2        kubeguide/tomcat-app@sha256:7a9193c2e5c6c74b4ad49a8abbf75373d4ab76c8f8db87672dc526b96ac69ac4   "catalina.sh run"        15 minutes ago           Up 15 minutes                               k8s_myweb_myweb-qqmp8_default_3dc7da86-5b20-11e8-9cc0-000c29c83e1f_0
cbdc283633ce        kubeguide/tomcat-app@sha256:7a9193c2e5c6c74b4ad49a8abbf75373d4ab76c8f8db87672dc526b96ac69ac4   "catalina.sh run"        16 minutes ago           Up 16 minutes                               k8s_myweb_myweb-sz64h_default_3dc89ceb-5b20-11e8-9cc0-000c29c83e1f_0
f8416f5e72e9        k8s.gcr.io/pause-amd64:3.1                                                                     "/pause"                 17 minutes ago           Up 17 minutes                               k8s_POD_myweb-qqmp8_default_3dc7da86-5b20-11e8-9cc0-000c29c83e1f_0
70b6cd00594a        k8s.gcr.io/pause-amd64:3.1                                                                     "/pause"                 17 minutes ago           Up 17 minutes                               k8s_POD_myweb-sz64h_default_3dc89ceb-5b20-11e8-9cc0-000c29c83e1f_0

3、 創建Service,定義 tomcat-service.yaml:

apiVersion: v1
kind: Service
metadata: 
  name: myweb
spec:
  type: NodePort      # 定義外網訪問模式
  ports:
    - port: 8080
      nodePort: 30001   # 外網訪問的端口,映射的本地宿主機端口
  selector:
    app: myweb

4、驗證:

[root@node-1 ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          19h
mysql        ClusterIP   10.110.213.104   <none>        3306/TCP         1h
myweb        NodePort    10.102.243.124   <none>        8080:30001/TCP   5m

[root@node-1 ~]# netstat -lntp|grep 30001
tcp6       0      0 :::30001                :::*                    LISTEN      2763/kube-proxy 

[root@node-2 ~]# netstat -lntp|grep 30001
tcp6       0      0 :::30001                :::*                    LISTEN      2362/kube-proxy    

通過訪問Master或node節點的30001端口可以訪問到tomcat默認頁面。

5、如果要刪除一個service 執行:

kubectl delete service  mysql

提示:刪除pod 後會自動創建一個新的pod,刪除node上運行的容器也會自動創建一個新的容器。

Kuberbetes1.10 集群部署