1. 程式人生 > >Kubernetes容器化工具Kind實踐部署Kubernetes v1.18.x 版本, 釋出WordPress和MySQL

Kubernetes容器化工具Kind實踐部署Kubernetes v1.18.x 版本, 釋出WordPress和MySQL

## Kind 介紹 [Kind](https://kind.sigs.k8s.io/)是Kubernetes In Docker的縮寫,顧名思義是使用Docker容器作為Node並將Kubernetes部署至其中的一個工具。官方文件中也把Kind作為一種本地叢集搭建的工具進行推薦。預設情況下,Kind會先下載kindest/node映象,該映象包含kubernetes的主要元件,當映象節點準備好時,Kind使用kubeadm進行叢集的建立,內部使用containerd跑元件容器。最終,Kind只是為了方便測試kubernetes叢集的,且不可用於生產環境。 ![](https://raw.githubusercontent.com/PassZhang/passzhang.github.io/images-picgo/20200714154918.png) ## 部署Kind Kind使用Golang進行開發,在倉庫的Release頁面,已經上傳了構建好的二進位制,支援多種作業系統,可直接按需下載進行使用。 ``` wget -O /usr/local/bin/kind https://github.com/kubernetes-sigs/kind/releases/download/v0.8.1/kind-linux-amd64 && chmod +x /usr/local/bin/kind # kind v0.8.1版本支援最新kubernetes v1.18.2叢集 ``` **安裝docker** ``` yum-config-manager --add-repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo yum install -y docker-ce ``` **部署kubectl** ``` wget -O /usr/local/bin/kubctl https://storage.googleapis.com/kubernetes-release/release/v1.18.5/bin/linux/amd64/kubectl chmod +x /usr/local/bin/kubectl ``` ## 建立kind單叢集 ### 使用kind命令建立 **使用`kind create` 建立叢集,預設是單節點叢集。** ``` # kind create cluster --name test Creating cluster "test" ... ✓ Ensuring node image (kindest/node:v1.18.2) ✓ Preparing nodes ✓ Creating kubeadm config ✓ Starting control-plane ️ ✓ Installing CNI ✓ Installing StorageClass Cluster creation complete. You can now use the cluster with: export KUBECONFIG="$(kind get kubeconfig-path --name="test")" kubectl cluster-info ``` **在docker環境下,會啟動一個映象** ``` CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2e0a5e15a4a0 kindest/node:v1.18.2 "/usr/local/bin/entr…" 14 minutes ago Up 14 minutes 45319/tcp, 127.0.0.1:45319->6443/tcp test-control-plane ``` **檢視叢集資訊** ``` export KUBECONFIG="$(kind get kubeconfig-path --name="test")" echo 'export KUBECONFIG="$(kind get kubeconfig-path --name=test)"' >> /root/.bashrc kubectl cluster-info Kubernetes master is running at https://localhost:45319 KubeDNS is running at https://localhost:45319/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME test-control-plane Ready master 16m v1.18.2 172.17.0.2 Ubuntu Disco Dingo (development branch) 3.10.0-693.el7.x86_64 containerd://1.2.6-0ubuntu1 kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system coredns-fb8b8dccf-6r58d 1/1 Running 0 17m kube-system coredns-fb8b8dccf-bntk8 1/1 Running 0 17m kube-system etcd-test-control-plane 1/1 Running 0 17m kube-system ip-masq-agent-qww8n 1/1 Running 0 17m kube-system kindnet-vbz6w 1/1 Running 0 17m kube-system kube-apiserver-test-control-plane 1/1 Running 0 16m kube-system kube-controller-manager-test-control-plane 1/1 Running 0 17m kube-system kube-proxy-wf7dq 1/1 Running 0 17m kube-system kube-scheduler-test-control-plane 1/1 Running 0 16m ``` **啟動nginx app** ``` kubectl run nginx --image nginx:1.17.0-alpine --restart=Never --port 80 --labels="app=nginx-test" kubectl port-forward --address 0.0.0.0 pod/nginx 8080:80 curl localhost:8080 ``` ### **指定配置檔案建立** ``` # cat kube-config.yaml kind: Cluster apiVersion: kind.sigs.k8s.io/v1alpha3 kubeadmConfigPatches: - | apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration metadata: name: config networking: serviceSubnet: 10.0.0.0/16 imageRepository: registry.aliyuncs.com/google_containers nodeRegistration: kubeletExtraArgs: pod-infra-container-image: registry.aliyuncs.com/google_containers/pause:3.1 - | apiVersion: kubeadm.k8s.io/v1beta2 kind: InitConfiguration metadata: name: config networking: serviceSubnet: 10.0.0.0/16 imageRepository: registry.aliyuncs.com/google_containers nodes: # 指定節點,預設是一個節點 - role: control-plane # kind create cluster --name test2 --config kube-config.yaml Creating cluster "test2" ... ✓ Ensuring node image (kindest/node:v1.18.2) ✓ Preparing nodes ✓ Creating kubeadm config ✓ Starting control-plane ️ ✓ Installing CNI ✓ Installing StorageClass Cluster creation complete. You can now use the cluster with: export KUBECONFIG="$(kind get kubeconfig-path --name="test2")" kubectl cluster-info ``` ## 建立kind-ha叢集 只能通過配置檔案來宣告ha叢集配置 ``` # cat kind-ha-config.yaml kind: Cluster apiVersion: kind.sigs.k8s.io/v1alpha3 kubeadmConfigPatches: - | apiVersion: kubeadm.k8s.io/v1beta2 kind: ClusterConfiguration metadata: name: config networking: serviceSubnet: 10.0.0.0/16 imageRepository: registry.aliyuncs.com/google_containers nodeRegistration: kubeletExtraArgs: pod-infra-container-image: registry.aliyuncs.com/google_containers/pause:3.1 - | apiVersion: kubeadm.k8s.io/v1beta2 kind: InitConfiguration metadata: name: config networking: serviceSubnet: 10.0.0.0/16 imageRepository: registry.aliyuncs.com/google_containers nodes: #主要修改這個位置,增加role,指定node節點,工作節點名稱必須為worker,master節點必須為control-plane - role: control-plane - role: control-plane - role: control-plane - role: worker - role: worker - role: worker # kind create cluster --name test-ha --config kind-ha-config.yaml Creating cluster "test-ha" ... ✓ Ensuring node image (kindest/node:v1.18.2) ✓ Preparing nodes ✓ Configuring the external load balancer ⚖️ ✓ Creating kubeadm config ✓ Starting control-plane ️ ✓ Installing CNI ✓ Installing StorageClass ✓ Joining more control-plane nodes ✓ Joining worker nodes Cluster creation complete. You can now use the cluster with: export KUBECONFIG="$(kind get kubeconfig-path --name="test3")" kubectl cluster-info # kubectl get nodes NAME STATUS ROLES AGE VERSION test3-control-plane Ready master 7m44s v1.18.2 test3-control-plane2 Ready master 4m59s v1.18.2 test3-control-plane3 Ready master 2m18s v1.15.0 test3-worker Ready 110s v1.15.0 test3-worker2 Ready 109s v1.15.0 test3-worker3 Ready 105s v1.15.0 ``` ## 常用操作 kind 是基於 docker 的,那麼我們再來看下 docker 資源,來驗證一下是否真的是基於 docker 的? ``` # 本機執行,就會提示有個docker容器正在執行,可以看到 docker 裡有一個 container,而 kind 建立的叢集就是基於這個 container 的,如果你直接刪掉了這個 container,通過 kind 建立的 k8s 叢集也會有問題 docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2e0a5e15a4a0 kindest/node:v1.18.2 "/usr/local/bin/entr…" 14 minutes ago Up 14 minutes 45319/tcp, 127.0.0.1:45319->6443/tcp test-control-plane ``` 再來看一下 network,執行 `docker network ls`,可以看到有一個名稱為 kind 的 network。 ``` docker network ls NETWORK ID NAME DRIVER SCOPE 94de31154cb7 bridge bridge local 0c31de104d44 host host local a667b873436d kind bridge local 6083dbc308a4 none null local ``` 我們可以進一步探究 kind-control-plane(就是上面的 docker container) 通過 `docker exec kind-control-plane crictl ps` 獲取這個容器內部的執行容器列表,這個容器內部通過 `crictl` 來操作容器,可以參考 https://github.com/kubernetes-sigs/cri-tools,crtctl 主要用來管理容器,命令使用和docker命令是一樣,可以通過 `docker exec kind-control-plane crictl help` 幫助檢視命令使用方法。 ``` # master 節點 docker exec kind-ha-control-plane crictl ps CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID 4b62cd954c86a ace0a8c17ba90 18 minutes ago Running kube-controller-manager 3 8f000bb1c20f3 90552a29c50d9 db10073a6f829 19 minutes ago Running local-path-provisioner 8 7e648bc7297b1 268f41443c426 a3099161e1375 19 minutes ago Running kube-scheduler 4 a64377f98d627 aa3fea2edc80d 67da37a9a360e 3 hours ago Running coredns 0 719884414c5f4 04c58978f5395 67da37a9a360e 3 hours ago Running coredns 0 da6e08629ac71 110429a5a873b 2186a1a396deb 3 hours ago Running kindnet-cni 0 5359903320ef9 1c125b02f6300 0d40868643c69 3 hours ago Running kube-proxy 0 9ba4d0a1fdd3d 0301cd4d26d9c 6ed75ad404bdd 3 hours ago Running kube-apiserver 0 4905e2b2a8a1a 435ee12a45bff 303ce5db0e90d 3 hours ago Running etcd 0 96f4e9190bede # worker節點 docker exec kind-ha-worker crictl ps CONTAINER IMAGE CREATED STATE NAME ATTEMPT POD ID 5e82bf4756b6f bfba26ca350c1 21 minutes ago Running nginx 0 78d1324b8b1a1 ea02b20040341 0d40868643c69 3 hours ago Running kube-proxy 0 de6a57d0b7381 c2aa986df532f 2186a1a396deb 3 hours ago Running kindnet-cni 1 ebea7a329cfe0 ``` **獲取 k8s 叢集所有資源示例** ``` kubectl get all --all-namespaces ``` **獲取叢集外部的config配置配置檔案** ``` kind get kubeconfig --name kind-ha ``` **獲取叢集內部的config配置配置檔案(一般獲取外部就夠用了)** ``` kind get kubeconfig --internal --name kind-ha ``` **刪除叢集(清理很方便)** ``` kind delete cluster --name test ``` **掛載檔案** ``` nodes: - role: control-plane extraMounts: - containerPath: /etc/docker/daemon.json hostPath: /etc/docker/daemon.json readOnly: true ``` **暴露埠方法1** ``` nodes: - role: control-plane extraPortMappings: - containerPort: 30080 hostPort: 30080 ``` > 有時候我們想暴露svc的埠給外部訪問,因為kubernetes的節點是在docker容器中,所以還需要容器暴露svc的埠,外部才能通過宿主機訪問。 **暴露埠方法2** ``` # 使用埠轉發的方式 kubectl port-forward --address 0.0.0.0 pod/nginx 8080:80 ``` **從私有倉庫下載映象** ``` docker exec test-drone-control-plane bash -c "sed -i '56a\ [plugins.cri.registry.mirrors.\"192.168.77.134:5000\"]' /etc/containerd/config.toml" docker exec test-drone-control-plane bash -c "sed -i '57a\ endpoint = [\"http://192.168.77.134:5000\"]' /etc/containerd/config.toml" docker exec test-drone-control-plane bash -c "cat /etc/containerd/config.toml" docker exec test-drone-control-plane bash -c 'kill -s SIGHUP $(pgrep containerd)' COPY ``` > 還可以通過掛載檔案的方式,掛載containerd的配置檔案 **重啟叢集** ``` docker stop test-drone-control-plane docker start test-drone-control-plane COPY ``` 總之,kind可以很方便的在docker環境下建立測試叢集,而不汙染我們的宿主機,給我們測試提供了很大的便利。 ## 示例:使用持久卷部署WordPress和MySQL 本教程向您展示如何使用Kind部署WordPress網站和MySQL資料庫。這兩個應用程式都使用PersistentVolumes和PersistentVolumeClaims來儲存資料。 [PersistentVolume](https://kubernetes.io/docs/concepts/storage/persistent-volumes/)(PV)是已經由管理員手動供應,或動態地使用由Kubernetes置備叢集中的一塊儲存的[StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes)。[PersistentVolumeClaim](https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)(PVC)是由能夠由PV滿足使用者對於儲存的請求。PersistentVolumes和PersistentVolumeClaims與Pod生命週期無關,並通過重新啟動,重新計劃甚至刪除Pod來保留資料。 > **警告:**此部署不適合生產用例,因為它使用單例項WordPress和MySQL Pods。考慮使用[WordPress Helm Chart](https://github.com/kubernetes/charts/tree/master/stable/wordpress)在生產中部署WordPress。 > **注意:**本教程中提供的檔案使用的是GA Deployment API,並且特定於kubernetes 1.9和更高版本。如果您希望將本教程與Kubernetes的早期版本一起使用,請相應地更新API版本,或參考本教程的早期版本。 ### 目標 - 建立PersistentVolumeClaims和PersistentVolumes - 建立一個`kustomization.yaml`與 - Secret密碼配置 - MySQL資源配置 - WordPress資源配置 - 通過以下方式應用Kustomization目錄 `kubectl apply -k ./` - 清理 ### 在你開始之前 您需要具有Kubernetes叢集,並且必須將kubectl命令列工具配置為與叢集通訊。如果還沒有叢集,則可以使用[Minikube](https://kubernetes.io/docs/setup/learning-environment/minikube/)或者是Kind建立一個叢集,也 可以使用以下Kubernetes遊樂場之一: - [katacoda](https://www.katacoda.com/courses/kubernetes/playground) - [play-Kubernetes](http://labs.play-with-k8s.com/) 要檢查版本,請輸入`kubectl version`。此頁面上顯示的示例適用於`kubectl`1.14及更高版本,上面我們已經建立了kind-ha叢集,直接執行後面的步驟既可。 ``` kubectl version Client Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.5", GitCommit:"e6503f8d8f769ace2f338794c914a96fc335df0f", GitTreeState:"clean", BuildDate:"2020-06-26T03:47:41Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"} Server Version: version.Info{Major:"1", Minor:"18", GitVersion:"v1.18.2", GitCommit:"52c56ce7a8272c798dbc29846288d7cd9fbae032", GitTreeState:"clean", BuildDate:"2020-04-16T11:48:36Z", GoVersion:"go1.13.9", Compiler:"gc", Platform:"linux/amd64"} ``` 下載以下配置檔案: 1. [mysql-deployment.yaml](https://kubernetes.io/examples/application/wordpress/mysql-deployment.yaml) 2. [wordpress-deployment.yaml](https://kubernetes.io/examples/application/wordpress/wordpress-deployment.yaml) ### 建立PersistentVolumeClaims和PersistentVolumes MySQL和Wordpress都需要一個PersistentVolume來儲存資料。他們的PersistentVolumeClaims將在部署步驟中建立。 許多叢集環境都安裝了預設的StorageClass。如果在PersistentVolumeClaim中未指定StorageClass,則使用群集的預設StorageClass。 建立PersistentVolumeClaim後,將根據StorageClass配置動態設定PersistentVolume。 ``` # 檢視StorageClass kubectl get sc kubectl describe sc $(kubectl get sc |grep default|awk 'NR==2{print $1}') ``` > **警告:**在本地叢集中,預設的StorageClass使用`hostPath`配置程式。`hostPath`該卷僅適用於開發和測試。有了`hostPath`卷,您的資料`/tmp`將駐留在Pod排程到的節點上,並且不會在節點之間移動。如果Pod死亡並被排程到群集中的另一個節點,或者該節點被重新引導,則資料將丟失。 > **注意:**如果要啟動需要使用`hostPath`配置程式的群集,則`--enable-hostpath-provisioner`必須在`controller-manager`元件中設定該標誌。 > **注意:**如果您有一個在Kubernetes Engine上執行的Kubernetes叢集,請遵循[本指南](https://cloud.google.com/kubernetes-engine/docs/tutorials/persistent-disk)。 ### 建立一個Secret密碼檔案kustomization.yaml [secret](https://kubernetes.io/docs/concepts/configuration/secret/)是一個物件,其儲存了一塊如密碼或金鑰的敏感資料。從1.14開始,`kubectl`支援使用kustomization檔案管理Kubernetes物件。您可以通過中的生成器建立Secret `kustomization.yaml`。 `kustomization.yaml`從以下命令中新增一個Secret生成器。您將需要替換`YOUR_PASSWORD`為您要使用的密碼。 ```shell cat <./kustomization.yaml secretGenerator: - name: mysql-pass literals: - password=YOUR_PASSWORD EOF ``` ### 為MySQL和WordPress新增資源配置 以下清單描述了單例項MySQL部署。MySQL容器將PersistentVolume掛載在/ var / lib / mysql。在`MYSQL_ROOT_PASSWORD`環境變數設定從secret資料庫密碼。 [`application/wordpress/mysql-deployment.yaml`](https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/wordpress/mysql-deployment.yaml) ``` apiVersion: v1 kind: Service metadata: name: wordpress-mysql labels: app: wordpress spec: ports: - port: 3306 selector: app: wordpress tier: mysql clusterIP: None --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-pv-claim labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi --- apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: wordpress-mysql labels: app: wordpress spec: selector: matchLabels: app: wordpress tier: mysql strategy: type: Recreate template: metadata: labels: app: wordpress tier: mysql spec: containers: - image: mysql:5.6 name: mysql env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password ports: - containerPort: 3306 name: mysql volumeMounts: - name: mysql-persistent-storage mountPath: /var/lib/mysql volumes: - name: mysql-persistent-storage persistentVolumeClaim: claimName: mysql-pv-claim ``` 以下清單描述了單例項WordPress部署。WordPress容器將PersistentVolume安裝在`/var/www/html`用於網站資料檔案的位置。在`WORDPRESS_DB_HOST`環境變數設定上面定義的MySQL服務的名稱,WordPress會由服務訪問資料庫。在 `WORDPRESS_DB_PASSWORD`環境變數設定從生成的祕密kustomize資料庫密碼。 [`application/wordpress/wordpress-deployment.yaml`](https://raw.githubusercontent.com/kubernetes/website/master/content/en/examples/application/wordpress/wordpress-deployment.yaml) ``` application/wordpress/wordpress-deployment.yaml apiVersion: v1 kind: Service metadata: name: wordpress labels: app: wordpress spec: ports: - port: 80 selector: app: wordpress tier: frontend type: LoadBalancer --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: wp-pv-claim labels: app: wordpress spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi --- apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: wordpress labels: app: wordpress spec: selector: matchLabels: app: wordpress tier: frontend strategy: type: Recreate template: metadata: labels: app: wordpress tier: frontend spec: containers: - image: wordpress:4.8-apache name: wordpress env: - name: WORDPRESS_DB_HOST value: wordpress-mysql - name: WORDPRESS_DB_PASSWORD valueFrom: secretKeyRef: name: mysql-pass key: password ports: - containerPort: 80 name: wordpress volumeMounts: - name: wordpress-persistent-storage mountPath: /var/www/html volumes: - name: wordpress-persistent-storage persistentVolumeClaim: claimName: wp-pv-claim ``` 使用curl 命令直接下載配置檔案 1. 下載MySQL部署配置檔案。 ```shell curl -LO https://k8s.io/examples/application/wordpress/mysql-deployment.yaml ``` 2. 下載WordPress配置檔案。 ```shell curl -LO https://k8s.io/examples/application/wordpress/wordpress-deployment.yaml ``` 3. 將它們新增到`kustomization.yaml`檔案。 ``` cat <>./kustomization.yaml resources: - mysql-deployment.yaml - wordpress-deployment.yaml EOF ``` ### 執行並驗證 在`kustomization.yaml`包含用於部署WordPress網站和MySQL資料庫的所有資源。您可以通過以下方式啟動應用 ```shell kubectl apply -k ./ ``` 現在,您可以驗證所有物件是否存在。 1. 通過執行以下命令來驗證機密是否存在: ```shell kubectl get secrets ``` 響應應如下所示: ```shell NAME TYPE DATA AGE mysql-pass-c57bb4t7mf Opaque 1 9s ``` 2. 驗證是否已動態配置PersistentVolume。 ```shell kubectl get pvc ``` > **注意:**設定和繫結PV可能要花費幾分鐘。 響應應如下所示: ```shell NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE mysql-pv-claim Bound pvc-8cbd7b2e-4044-11e9-b2bb-42010a800002 20Gi RWO standard 77s wp-pv-claim Bound pvc-8cd0df54-4044-11e9-b2bb-42010a800002 20Gi RWO standard 77s ``` 3. 通過執行以下命令來驗證Pod是否正在執行: ```shell kubectl get pods ``` > **注意:** Pod的狀態最多可能需要幾分鐘的時間`RUNNING`。 響應應如下所示: ``` NAME READY STATUS RESTARTS AGE wordpress-mysql-1894417608-x5dzt 1/1 Running 0 40s ``` 4. 通過執行以下命令來驗證服務是否正在執行: ```shell kubectl get services wordpress ``` 響應應如下所示: ``` NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE wordpress LoadBalancer 10.0.0.89 80:32406/TCP 4m ``` > **注意:** Minikube只能通過公開服務`NodePort`。EXTERNAL-IP始終處於掛起狀態。 > > ​ 當前我使用的是kind建立叢集,可以直接通過埠轉發方式,進行訪問WordPress頁面 5. 執行以下命令以獲取WordPress服務的IP地址: ```shell kubectl port-forword --address 0.0.0.0 svc/wordpress 8000:80 ``` 6. 複製IP地址,然後將頁面載入到瀏覽器中以檢視您的站點。 您應該看到類似於以下螢幕截圖的WordPress設定頁面。 ![wordpress初始化](https://raw.githubusercontent.com/kubernetes/examples/master/mysql-wordpress-pd/WordPress.png) > **警告:**請勿在此頁面上保留WordPress安裝。如果其他使用者找到了它,他們可以在您的例項上建立一個網站並使用它來提供惡意內容。 > > 通過建立使用者名稱和密碼來安裝WordPress或刪除您的例項。 ### 刪除WordPress 1. 執行以下命令以刪除您的金鑰,部署,服務和PersistentVolumeClaims: ```shell kubectl delete -k .