深入k8s:k8s部署&在k8s中運行第一個程序


更新了集群環境的搭建,與單機實驗環境的搭建

014f5a5f1568aca801215aa0a9da5d.jpg@3000w_1l_0o_100sh

搭建k8s單點實驗環境

由於在國內網絡問題,我們無法很好的使用minikube進行部署k8s實驗環境,所以可以使用阿里提供的minikube進行搭建。除了minikube,也可以使用kubeasz進行部署。

下面我基於kubeaze給出部署方法,部署方法都參照https://github.com/easzlab/kubeasz,其中附上我的踩坑經驗。

1.基礎系統配置

  • 准備一台虛機配置內存2G/硬盤30G以上
  • 最小化安裝Ubuntu 16.04 server或者CentOS 7 Minimal
  • 配置基礎網絡、更新源、SSH登錄等

注意: 確保在干凈的系統上開始安裝,不能使用曾經裝過kubeadm或其他k8s發行版的環境

2.下載文件

  • 下載工具腳本easzup,舉例使用kubeasz版本2.2.1
export release=2.2.1
curl -C- -fLO --retry 3 https://github.com/easzlab/kubeasz/releases/download/${release}/easzup
chmod +x ./easzup
  • 使用工具腳本下載

默認下載最新推薦k8s/docker等版本,使用命令./easzup 查看工具腳本的幫助信息

設置docker源:

{
  "registry-mirrors": [
    "https://eig40bb2.mirror.aliyuncs.com",
    "https://docker.mirrors.ustc.edu.cn",
    "http://hub-mirror.c.163.com",
    "https://reg-mirror.qiniu.com"
  ],
  "max-concurrent-downloads": 10,
  "log-driver": "json-file",
  "log-level": "warn",
  "log-opts": {
    "max-size": "10m",
    "max-file": "3"
    },
  "data-root": "/var/lib/docker"
}

添加完之后刷新一下配置:

systemctl daemon-reload
systemctl restart docker
# 舉例使用 k8s 版本 v1.18.2,docker 19.03.5
./easzup -D -d 19.03.5 -k v1.18.2
  • 可選下載離線系統包 (適用於無法使用yum/apt倉庫情形)
./easzup -P

上述腳本運行成功后,所有文件(kubeasz代碼、二進制、離線鏡像)均已整理好放入目錄/etc/ansible

  • /etc/ansible 包含 kubeasz 版本為 ${release} 的發布代碼
  • /etc/ansible/bin 包含 k8s/etcd/docker/cni 等二進制文件
  • /etc/ansible/down 包含集群安裝時需要的離線容器鏡像
  • /etc/ansible/down/packages 包含集群安裝時需要的系統基礎軟件

3.安裝集群

  • 容器化運行 kubeasz,詳見文檔
./easzup -S
  • 使用默認配置安裝 aio 集群
docker exec -it kubeasz easzctl start-aio

4.驗證安裝

如果提示kubectl: command not found,退出重新ssh登錄一下,環境變量生效即可

$ kubectl version         # 驗證集群版本     
$ kubectl get node        # 驗證節點就緒 (Ready) 狀態
$ kubectl get pod -A      # 驗證集群pod狀態,默認已安裝網絡插件、coredns、metrics-server等
$ kubectl get svc -A      # 驗證集群服務狀態

搭建k8s集群環境

我們打算搭建一個這樣的三節點的集群:

k8s集群圖

1. 准備服務器

首先3台虛機,搭建一個多主高可用集群。

  • 推薦內存2G/硬盤30G以上
  • 最小化安裝Ubuntu 16.04 server或者CentOS 7 Minimal
  • 配置基礎網絡、更新源、SSH登錄等

2. 在每個節點安裝ansible依賴工具

CentOS 7 請執行以下腳本:

# 文檔中腳本默認均以root用戶執行
yum update
# 安裝python
yum install python -y

安裝pip的時候先安裝

yum -y install epel-release

安裝pip

yum install git python-pip -y

pip 安裝 ansible

# CentOS 7
yum install git python-pip -y
# pip安裝ansible(國內如果安裝太慢可以直接用pip阿里雲加速)
pip install pip --upgrade -i https://mirrors.aliyun.com/pypi/simple/
pip install ansible==2.6.18 netaddr==0.7.19 -i https://mirrors.aliyun.com/pypi/simple/

在ansible控制端配置免密碼登錄

# 更安全 Ed25519 算法
ssh-keygen -t ed25519 -N '' -f ~/.ssh/id_ed25519
# 或者傳統 RSA 算法
ssh-keygen -t rsa -b 2048 -N '' -f ~/.ssh/id_rsa

ssh-copy-id 192.168.13.131
ssh-copy-id 192.168.13.132
ssh-copy-id 192.168.13.133

如果這一步不設置,那么在部署的時候無法訪問到相應的節點會報如下錯:

192.168.13.130 | UNREACHABLE! => {
    "changed": false,
    "msg": "SSH Error: data could not be sent to remote host \"192.168.13.130\". Make sure this host can be reached over ssh",
    "unreachable": true
}

3.在ansible控制端編排k8s安裝

  • 4.0 下載項目源碼
  • 4.1 下載二進制文件
  • 4.2 下載離線docker鏡像

推薦使用 easzup 腳本下載 4.0/4.1/4.2 所需文件;運行成功后,所有文件(kubeasz代碼、二進制、離線鏡像)均已整理好放入目錄/etc/ansible

# 下載工具腳本easzup,舉例使用kubeasz版本2.0.2
export release=2.0.2
curl -C- -fLO --retry 3 https://github.com/easzlab/kubeasz/releases/download/${release}/easzup
chmod +x ./easzup
# 使用工具腳本下載
./easzup -D

4.配置集群參數

  • 必要配置:cd /etc/ansible && cp example/hosts.multi-node hosts, 然后實際情況修改此hosts文件

    根據我們上圖的介紹,我們將hosts改成如下:

    # 'etcd' cluster should have odd member(s) (1,3,5,...)
    # variable 'NODE_NAME' is the distinct name of a member in 'etcd' cluster
    [etcd]
    192.168.13.131 NODE_NAME=etcd1
    192.168.13.132 NODE_NAME=etcd2
    192.168.13.133 NODE_NAME=etcd3
    
    # master node(s)
    [kube-master]
    192.168.13.131
    
    # work node(s)
    [kube-node]
    192.168.13.131
    192.168.13.132
    192.168.13.133
    
    ...
    

    只改如上配置,其他的可不動。

  • 驗證ansible 安裝:ansible all -m ping 正常能看到節點返回 SUCCESS

  • 開始安裝 如果你對集群安裝流程不熟悉,請閱讀項目首頁 安裝步驟 講解后分步安裝,並對 每步都進行驗證

    # 分步安裝
    ansible-playbook 01.prepare.yml
    ansible-playbook 02.etcd.yml
    ansible-playbook 03.docker.yml
    ansible-playbook 04.kube-master.yml
    ansible-playbook 05.kube-node.yml
    ansible-playbook 06.network.yml
    ansible-playbook 07.cluster-addon.yml
    
  • 如果不想分步安裝,那么可以一步安裝:

    # 一步安裝
    #ansible-playbook 90.setup.yml
    

在k8s中運行一個程序

編寫YAML文件

Kubernetes 跟 Docker 等很多項目最大的不同,就在於它不推薦你使用命令行的方式直接運行容器,而是希望你用 YAML 文件的方式,然后用這樣一句指令把它運行起來:

$ kubectl create -f 我的配置文件

yaml如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80

Kind 字段,指定了這個 API 對象的類型(Type),是一個 Deployment。Deployment,是一個定義多副本應用的對象,Deployment 還負責在 Pod 定義發生變化時,對每個副本進行滾動更新。

像這樣使用一種 API 對象(Deployment)管理另一種 API 對象(Pod)的方法,在Kubernetes 中,叫作“控制器”模式(controller pattern)。

一個 Kubernetes 的 API 對象的定義,大多可以分為 Metadata 和 Spec 兩個部分。前者存放的是這個對象的元數據,對所有 API 對象來說,這一部分的字段和格式基本上是一樣的;而后者存放的,則是屬於這個對象獨有的定義,用來描述它所要表達的功能。

spec.replicas是2,表示定義的 Pod 副本個數。

spec.template作用是描述了我想要創建的 Pod 的細節。spec.containers.image表示容器鏡像是nginx:1.7.9,containerPort表示監聽的端口是80。

Labels 字段可以用來過濾控制對象,在上面這個 YAML 文件中,Deployment 會把所有正在運行的、攜帶“app: nginx”標簽的 Pod 識別為被管理的對象,並確保這些 Pod 的總數嚴格等於兩個。

spec.selector.matchLabels是用來定義過濾規則的,一般稱之為:Label Selector。

創建一個pod

在理解完上面的知識后,我們可以運行起來:

$ kubectl create -f nginx-deployment.yaml

然后,通過 kubectl get 命令檢查這個 YAML 運行起來的狀態是不是與我們預期的一致:

$ kubectl get pods -l app=nginx
NAME                                READY     STATUS    RESTARTS   AGE
nginx-deployment-67594d6bf6-9gdvr   1/1       Running   0          10m
nginx-deployment-67594d6bf6-v6j7w   1/1       Running   0          10m

-l表示獲取所有匹配 app: nginx 標簽的 Pod。

注意:在命令行中,所有 key-value 格式的參數,都使用“=”而非“:”表示。

此外,我們還可以使用kubectl describe 命令,查看一個 API 對象的細節:

$ kubectl describe pod nginx-deployment-67594d6bf6-9gdvr
Name:               nginx-deployment-67594d6bf6-9gdvr
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               node-1/10.168.0.3
Start Time:         Thu, 16 Aug 2018 08:48:42 +0000
Labels:             app=nginx
                    pod-template-hash=2315082692
Annotations:        <none>
Status:             Running
IP:                 10.32.0.23
Controlled By:      ReplicaSet/nginx-deployment-67594d6bf6
...
Events:

  Type     Reason                  Age                From               Message

  ----     ------                  ----               ----               -------
  
  Normal   Scheduled               1m                 default-scheduler  Successfully assigned default/nginx-deployment-67594d6bf6-9gdvr to node-1
  Normal   Pulling                 25s                kubelet, node-1    pulling image "nginx:1.7.9"
  Normal   Pulled                  17s                kubelet, node-1    Successfully pulled image "nginx:1.7.9"
  Normal   Created                 17s                kubelet, node-1    Created container
  Normal   Started                 17s                kubelet, node-1    Started container

上面詳細信息中,在 Kubernetes 執行的過程中,對 API 對象的所有重要操作都會記錄到Events里面。

為pod進行版本升級

如果我們要對這個 Nginx 服務進行升級,把它的鏡像版本從 1.7.9 升級為 1.8,那么我們可以修改一下YAML文件:

...    
    spec:
      containers:
      - name: nginx
        image: nginx:1.8 #這里被從1.7.9修改為1.8
        ports:
      - containerPort: 80

然后使用kubectl replace 指令來完成k8s集群中更新:

$ kubectl replace -f nginx-deployment.yaml

我們也可以使用kubectl apply 命令,來統一進行 Kubernetes 對象的創建和更新操作,具體做法如下所示:

$ kubectl apply -f nginx-deployment.yaml

# 修改nginx-deployment.yaml的內容

$ kubectl apply -f nginx-deployment.yaml

使用kubectl apply 命令是 Kubernetes“聲明式 API”所推薦的使用方法。也就是說,作為用戶,你不必關心當前的操作是創建,還是更新,你執行的命令始終是 kubectl apply,而 Kubernetes 則會根據 YAML 文件的內容變化,自動進行具體的處理。

聲明一個 Volume

在 Kubernetes 中,Volume 是屬於 Pod 對象的一部分。所以,我們就需要修改這個 YAML 文件里的 template.spec 字段,如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.8
        ports:
        - containerPort: 80
        volumeMounts:
        - mountPath: "/usr/share/nginx/html"
          name: nginx-vol
      volumes:
      - name: nginx-vol
        emptyDir: {}

我們在上面定義了volumes字段,名字叫做nginx-vol,類型是 emptyDir。Pod 中的容器,使用的是 volumeMounts 字段來聲明自己要掛載哪個 Volume,並通過 mountPath 字段來定義容器內的 Volume 目錄,比如:/usr/share/nginx/html。

emptyDir表示,Kubernetes 也會在宿主機上創建一個臨時目錄,這個目錄將來就會被綁定掛載到容器所聲明的 Volume 目錄上。

然后使用kubectl apply 指令,更新這個Deployment,然后使用 kubectl describe 查看一下最新的 Pod:

...
Containers:
  nginx:
    Container ID:   docker://07b4f89248791c2aa47787e3da3cc94b48576cd173018356a6ec8db2b6041343
    Image:          nginx:1.8
    ...
    Environment:    <none>
    Mounts:
      /usr/share/nginx/html from nginx-vol (rw)
...
Volumes:
  nginx-vol:
    Type:    EmptyDir (a temporary directory that shares a pod's lifetime)

最后,你還可以使用 kubectl exec 指令,進入到這個 Pod 當中(即容器的 Namespace 中)查看這個 Volume 目錄:

$ kubectl exec -it nginx-deployment-5c678cfb6d-lg9lw -- /bin/bash
# ls /usr/share/nginx/html

如果要刪除這個Nginx Deployment 的話,直接執行:

$ kubectl delete -f nginx-deployment.yaml

總結

  1. 與k8s進行交互盡量選擇yaml文件交互;
  2. 我們可以使用kubectl create 命令創建一個pod;
  3. 想要獲取目前pod的狀態可以使用kubectl get pods命令;
  4. 使用kubectl describe pod 可以查看某個pod的詳細信息;
  5. 如果想要對pod更新最好使用kubectl apply -f ,這樣可以做到更加無感的創建pod或更新;
  6. 我們可以使用Volumes來掛載卷;
  7. 使用kubectl delete -f可以刪除一個pod;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM