自 18.06 Stable 版本起,安裝 Docker CE 會包含 Kubernetes,於本機執行,不能設定的 single-node cluster,作為開發及測試用。
以入門來說,是個好選擇,熟悉後再上 Google Kubernetes Engine 服務。
Deploy on Kubernetes
https://docs.docker.com/docker-for-windows/kubernetes/
———————————簡易的分隔線————————————
Docker with Kubernetes 名詞及結構︰
看起來超複雜?換個角度,在 Docker 基礎上加 K8s,只需留意 Cluster 內及 kubectl。
Cluster
只是在圈地,反正不能設定,現在先放置,去到 GCP ( Google Cloud Platform ) 再說。
Node
都說 single node cluster 了,甚麼是 node?如果不是 single node cluster 的話,node 可分為 master node 及 worker node。
打個比喻,現在你有間公司 ( cluster ),你是老闆 ( kubectl ),下面有四個員工 ( node ),一個高層 ( master node ),三個下屬 ( worker node )。
你給高層指令 ( 用 kubectl 透過 API Server ),高層發號司令 ( controller ),分派工作、資源、訊息等等東西,命令下屬做事。下屬做了甚麼事後,匯報給高層 ( 透過 API Server ),例如造好了某建設 ( TomEE Server )。
現在要開記者招待會,公告公司有甚麼重大服務推出 ( expose service ),希望公眾使用。何時有見過小職員能在記招說話?都是高層出面沾光……
以上假設很美好……如果是蚊型公司的話,就是 single node cluster,master node 是你,worker node 也是你,你不能分身,因此無人代替,只要你倒下,公司一起倒。
Pod
一個 node 裡面可以有很多個 container,通常是一個 pod 一個 container,為甚麼?看到 pod 裡有 volume 吧?K8s 目標在於 decoupled system,沒必要把 container 都往一個 pod 裡放,docker 起 pod 預設也是一個 pod 放一個 container 。
K8s 的 volume 概念與 Docker 不同,有更多選擇。Pod 死,未必連 volume 一起死,那是看你選了怎樣的 volume,詳情請參考以下官網。
Pod 的 IP 及 port 與 container 共享,只要在同一個pod,containers 都可以用 localhost 互相溝通。
Pod Overview
https://kubernetes.io/docs/concepts/workloads/pods/pod-overview/
Volumes
https://kubernetes.io/docs/concepts/storage/volumes/
Service
由於 K8s 設計包含 fault-tolerant 及 load-balance 等目標,並不會有固定 IP,那麼會有甚麼問題呢?
例如 JDBC connection 需要 URL 連接,問題是你不會知道實際 IP 是甚麼,這個時候需要靠 DNS 之類服務來固定實際名字,再由名字查出 IP 是甚麼。
把服務 ( 如 Derby、TomEE ) 打上 label,由多個 pod 拿著相同 label,然後使用者查冊 key-value pairs 後找到服務。
Services
https://kubernetes.io/docs/concepts/services-networking/service/
Labels and Selectors
https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors
Deployments
Kubernetes 要透過 deployment 建立 pod,docker 版 K8s 做法也差不多。
Deployments
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
Deploy on Kubernetes
https://docs.docker.com/docker-for-windows/kubernetes/
———————————簡易的分隔線————————————
開啟及設定 Kubernetes︰
選擇 context。
Enable K8s for windows CE
https://docs.docker.com/docker-for-windows/#kubernetes
———————————簡易的分隔線————————————
由於 .env 不能用在 docker stack deploy 指令,而且 volumes mount 要作修改,才可以 deploy。
yml 及 .env source
https://gist.github.com/IntegrityKnight/edc33f17c9cf7aeebaee794995eed341/c9010b34df88fb03bf7c2711dcf755aab8d0693a
Variable substitution———————————簡易的分隔線————————————
修改 yml 及 .env 檔︰
由於 .env 不能用在 docker stack deploy 指令,而且 volumes mount 要作修改,才可以 deploy。
yml 及 .env source
https://gist.github.com/IntegrityKnight/edc33f17c9cf7aeebaee794995eed341/c9010b34df88fb03bf7c2711dcf755aab8d0693a
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Please check "https://javatoybox.blogspot.com/2018/11/docker-kubernetes.html" | |
DERBY_IMAGE_TAG=v10.14.2.0 | |
TOMEE_IMAGE_TAG=v8-jre-7.1.0-plus | |
# for Windows "A:\\javatoybox\\Database\\" | |
# for Linux "~/Database" | |
# for k8s ( Windows 10 ) "//a/javatoybox/Database" | |
DERBY_MOUNT_MAPPING=//a/javatoybox/Database | |
# for windows "A:\javatoybox\GitHub_Local_Repo\docker-compose" | |
# for k8s ( Windows 10 ) "//a/javatoybox/GitHub_Local_Repo/docker-compose/" | |
TOMEE_MOUNT_MAPPING=//a/javatoybox/GitHub_Local_Repo/docker-compose/ | |
# test website "http://localhost:8080/TomEE-JNDI-Derby-Example/datasource.jsp" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: "3.7" | |
services: | |
db: | |
hostname: db | |
image: integrityknight/derby:${DERBY_IMAGE_TAG} | |
container_name: derby_db | |
ports: | |
- 1527:1527 | |
healthcheck: | |
disable: true | |
volumes: | |
- ${DERBY_MOUNT_MAPPING}:/Database | |
command: java -Dderby.stream.error.field=java.lang.System.out org.apache.derby.drda.NetworkServerControl start -h db | |
tomee: | |
hostname: tomee | |
depends_on: | |
- db | |
image: integrityknight/tomee:${TOMEE_IMAGE_TAG} | |
container_name: tomee_plus | |
ports: | |
- 8080:8080 | |
volumes: | |
- ${TOMEE_MOUNT_MAPPING}/webapps/:/usr/local/tomee/webapps | |
- ${TOMEE_MOUNT_MAPPING}/lib/:/usr/local/tomee/lib | |
- ${TOMEE_MOUNT_MAPPING}/conf/:/usr/local/tomee/conf |
Fixing Volumes in Docker Toolbox
在 project 的 working directory 中輸入以下 command, 結合 .env 與 yml,輸出做一個 yml。
然後嘗試做 deploy︰
- docker-compose config > k8s.yml
然後嘗試做 deploy︰
- docker stack deploy --compose-file k8s.yml mystack
失敗了…… 為甚麼?檔案輸出過程中,程式自動把 .env 的 ( / ) 轉換成 ( \ ) …… 拿去 linux container 用,當然出問題,所以只好自動手動修改輸出檔案。
用 replace 功能一次過替代檔案中 ( \ ),換成 ( / ),如果看不到 k8s.yml 檔案,refresh eclipse GUI 可以看到。
再嘗試 deploy …… 成功!
back slash and forword slash
https://stackoverflow.com/questions/1589930/so-what-is-the-right-direction-of-the-paths-slash-or-under-windows
Deploy on Kubernetes
———————————簡易的分隔線————————————
deploy 功能後,怎知道內裡有甚麼?這時候需要用 kubectl 去看。
使用 kubectl︰
查看 pod 及對外 service IP︰
deploy 功能後,怎知道內裡有甚麼?這時候需要用 kubectl 去看。
- kubectl get pods
- kubectl get services
圖中可看到 EXTERNAL-IP,是 localhost,所以可以試試在 browser 開來看看。
http://localhost:8080/TomEE-JNDI-Derby-Example/datasource.jsp
假如發生錯誤,可能是 Database 不正確關閉,而留下 .lck 檔案,手動刪除,再重新 deploy 一次。
移除 stack︰
用以下 command 可關閉 stack。不是即時關閉,要再用 kubectl get pods 確認是否關好。
- docker stack rm mystack
docker stack rm
kubectl cheatsheet
———————————簡易的分隔線————————————
總結︰
用 Docker 的 K8s 練習,然後再試 GCP 。GCP 優惠期有限,有一定認識後,再上 GCP,這樣做就不會浪費限時優惠在學習上。
Google Kubernetes Engine