Symbols count in article:
1.9k
Reading time:
8 mins.
Service 簡介和演示
- 不要直接使用和管理 Pods,為什麼?
- 當我們使用 ReplicaSet 或 ReplicaController 做水平擴展 Scale 的時候,Pods 有可能會被 Terminated
- 當我們使用 Deployment 的時候,我們去更新 Docker Image Version,舊的 Pods 會被 Terminated,新的 Pods 會被創建
- 創建 Service
kubectl expose
命令,會給我們的 pod 創建一個 Service,供外部訪問
- Service 主要有三種類型,一種叫 Cluster ip(只供 Cluster 內部訪問),一種叫 NodePort,一種叫外部的 Loadbalancer
- 另外也可以使用 DNS,但是 DNS 要 add-on
- 接續上次的 Pods,先讓 nginx 可以被外部訪問
kubectl expose pods nginx-pod
- 使用
kubectl get svc
會看到 nginx-pod 的 ip 10.104.59.208
- 進去 minikube 的裡面,
curl 10.104.59.208
,會回傳 nginx 服務
- 新增 deployment_python_http.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| apiVersion: apps/v1 kind: Deployment metadata: name: service-test spec: replicas: 2 selector: matchLabels: app: service_test_pod template: metadata: labels: app: service_test_pod spec: containers: - name: simple-http image: python:2.7 imagePullPolicy: IfNotPresent command: ["/bin/bash"] args: ["-c", "echo \"<p>Hello from $(hostname)</p>\" > index.html; python -m SimpleHTTPServer 8080"] ports: - name: http containerPort: 8080
|
- 先進去機器
minikube ssh
把 python Image 先 pull 下來
docker pull python:2.7
- 新增 Deployment
kubectl create -f deployment_python_http.yml
- 進去 minikube 裡面
minikube ssh
,分別對兩個 Pods 的 ip 執行 curl,就會回傳不同的 hostname
curl 172.17.0.6:8080
curl 172.17.0.7:8080
- 使用
kubectl get deployment
查看 deployment 名稱,並對外開放
kubectl expose deployment service-test
- 使用
kubectl get svc
會發現新增了一個 service-test,對 service-test 多次執行 curl,會發現每次返回的 hostname 都不一定一樣,也就是說,service 會自動做負載均衡
curl 10.99.229.174:8080
- 我們要做不停機更新,先在 minikube 裡面不停的 curl
while true; do curl 10.99.229.174:8080;done
- 用編輯的方式進行更新,使用以下指令會跳出 Deployment 的 yml 檔案,修改 args 為 new version of helloworld,並儲存
kubectl edit deployment service-test
- 使用
kubectl get pods
就會看到之前兩個 Pods Terminated,而且啟動了兩個新的 Pods,但是更新過程中,還是有幾秒鐘的版本穿插的問題,因為沒有使用 Rolling Update,詳細可參考 Rolling Update 文檔
NodePort 的 Service 以及 Label 的簡單實用
- 首先清理環境,把所有 Services 和 Pods 都刪除
- 在 K8s 裡面,幾乎所有的資源都可以設置 label,label 的形式是一對 key 和 value 組成,label 不只可以設置一個
- 先使用之前的 pod_nginx.yml 創建資源
kubectl create -f pod_nginx.yml
- 將端口開放,類型設置為 NodePort
kubectl expose pods nginx-pod --type=NodePort
- 使用
kubectl get svc
顯示 Service 的端口,再用 kubectl get node -o wide
顯示出 minikube 的 ip 地址,直接在本地瀏覽器輸入 http://192.168.99.101:32394/ 就可以訪問 nginx 服務了
- 先刪除 NodePort 的 Service
kubectl delete service nginx-pod
- 可以自己手動新增 Service,首先新增一個 service_nginx.yml,target port 的設置可以使用
cat pod_nginx.yml
打開之前新增 pod 的 yml,裡面就有定義 ports name 是 nginx port,這邊的 selector 就是創建資源的 label,可以使用 kubectl get pods --show-labels
查看 labels
1 2 3 4 5 6 7 8 9 10 11 12 13
| apiVersion: v1 kind: Service metadata: name: nginx-service spec: ports: - port: 32333 nodePort: 32333 targetPort: nginx-port protocol: TCP selector: app: nginx type: NodePort
|
- 使用
kubectl create -f service_nginx.yml
新增 Service,並使用 kubectl get svc
查看服務確實啟動,到本地瀏覽器輸入 http://192.168.99.101:33333/ 就可以訪問 nginx 服務了
- 新增 pod_busybox.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: v1 kind: Pod metadata: name: busybox-pod labels: app: busybox spec: nodeSelector: hardware: good containers: - name: busybox-container image: busybox command: - sleep - "360000"
|
- 使用
kubectl create -f pod_busybox.yml
創建 Pod,但是當用 kubectl get pods
查看,會看到這個 Pod 顯示 Pending,使用 kubectl get node --show-labels
查看 node 標籤會發現沒有 hardware:good 的標籤,所以才顯示 Pending
- 給 minikube 加上 label
kubectl label node minikube hardware=good
- 再使用
kubectl get pods
查看就會發現 busybox 的 pod 啟動了
- 總結:ClusterIP 只能是內部訪問,所以它不能提供服務,我們可以透過 NodePort 去提供服務,但是會有幾個問題,(1) NodePort 的範圍只能是 30000-32767,(2) Expose 會在所有節點上提供給外部訪問,所以 NodePort 在實際的 Production 環境也不怎麼使用,但是可以用,在 Production 環境大家用的比較多的就是 Loadbalancer 或是 ExternalName,Loadbalancer 需要結合雲服務商去使用,ExternalName 就是使用 DNS 服務
kubectl 指令補全
kubectl completion zsh
- 更新 zsh
source <(kubectl completion zsh)
使用 Kops 在 DigitalOcean 上面搭建 K8s 集群
- Kops Github Page:Kops 是用於 Production 級別的 K8s 安裝、升級和管理
- 註冊一個域名,把以下三個 NameServer 指向 DigitalOcean
- 進入 DigitalOcean API 介面,申請一個 Personal access tokens 和一個 Spaces access keys
- 在畫面右上角點擊 Create Space,新增一個空間,這邊的空間名是全網唯一的
- 使用 dig 指令查看域名狀態,如果都有回傳內容,代表網域生效
dig +short pcelab.info ns
dig +short pcelab.info soa
- 參考 DigitalOcean 文件創建 Cluster
- 設定參數
1 2 3 4 5 6 7 8
| export KOPS_STATE_STORE=do://<bucket-name> export DIGITALOCEAN_ACCESS_TOKEN=<access-token>
export S3_ENDPOINT=sgp1.digitaloceanspaces.com export S3_ACCESS_KEY_ID=<access-key-id> export S3_SECRET_ACCESS_KEY=<secret-key>
export KOPS_FEATURE_FLAGS="AlphaAllowDO"
|
- 使用 kops 新增 Cluster 和 Master 節點
kops create cluster --cloud=digitalocean --name=kops.pcelab.info --image=ubuntu-18-04-x64 --networking=weave --zones=sgp1 --ssh-public-key=~/.ssh/id_rsa.pub --node-size=s-1vcpu-1gb
- 驗證 Cluster
kops validate cluster
- 查看 Node 是否生成
kubectl get nodes --show-labels
- 進入 master 去做操作
ssh -i ~/.ssh/id_rsa admin@api.kops.pcelab.info
容器的基本監控
- 使用
docker ps
查看 Container,再使用 docker top [Container id]
就可以查看 Container 的進程,有點類似 Linux 內建的 top 功能
docker stats
可以實時打印出後台正在運行的 Container 的系統佔用狀態,包含佔了多少內存,多少 CPU,使用 ctrl + C 可以退出
- 在虛擬機上面安裝 Weave Scope,並修改權限
sudo curl -L git.io/scope -o /usr/local/bin/scope
sudo chmod a+x /usr/local/bin/scope
- 啟動 Weave Scope
scope launch 192.168.205.10
- 啟動後的畫面如下圖,進去可以去做一些操作
- 也可以同時監控兩台機器,需要在兩台機器上面都輸入以下命令
scope launch [機器 1 IP] [機器 2 IP]
Gitlab CI 安裝
- 設置一台 Ubuntu 的主機,安裝過程可以參考 Gitlab CI Runner 文檔
- 安裝 Docker
curl -sSL https://get.docker.com | sh
- 安裝 Gitlab CI Runner
1 2
| curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh | sudo bash sudo apt-get install gitlab-ci-multi-runner -y
|
- 查看是否正常運行
sudo gitlab-ci-multi-runner status
- 設置 Docker 權限
1 2 3
| sudo usermod -aG docker gitlab-runner sudo service docker restart sudo gitlab-ci-multi-runner restart
|
在 Hexo 使用 Gitlab CI
- 註冊 gitlab-runner,tag 輸入
hexo
,executor 輸入 docker
sudo gitlab-ci-multi-runner register
- 在後台 Gitlab 專案裡面選擇 Settings > CI/CD > Runner 就會看到剛剛新增的 Runner,並且選擇下面的 Variables 新增 SSH_PRIVATE_KEY,將本地的 ~/.ssh/id_rsa 的內容複製到 SSH_PRIVATE_KEY 的 Value
- 在 Hexo 目錄新增 .gitlab-ci.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| before_script: - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )' - eval $(ssh-agent -s) - ssh-add <(echo "$SSH_PRIVATE_KEY") - mkdir -p ~/.ssh - chmod 700 ~/.ssh - ssh-keyscan -t rsa gitlab.fishboneapps.com >> ~/.ssh/known_hosts ## Make sure that rsync is installed - 'which rsync || ( apt-get update -y && apt-get install rsync -y)'
stages: - build
build_job: stage: build tags: - hexo script: - npm -g install hexo -f --no-optional - npm cache verify - npm install -f --no-optional - hexo cl && hexo g - hexo deploy - echo "Deploy succssed!" cache: key: ${CI_BUILD_REF_NAME} paths: - node_modules/
|
- 將更新推送到 Gitlab 之後,進去專案的 CI/CD > Pipelines 就可以查看進度