Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Kubernetes 101

Avatar for Tommy Chen Tommy Chen
October 03, 2016

Kubernetes 101

Avatar for Tommy Chen

Tommy Chen

October 03, 2016
Tweet

More Decks by Tommy Chen

Other Decks in Technology

Transcript

  1. Build $ docker build --tag tommy351/my-server . Sending build context

    to Docker daemon 3.943 MB Step 1 : FROM scratch ---> Step 2 : COPY app / ---> 4c25e1b50576 Removing intermediate container 22b9992b6f64 Step 3 : EXPOSE 4000 ---> Running in 975456111f69 ---> 03095e7edf87 Removing intermediate container 975456111f69 Step 4 : CMD /app ---> Running in 9bc9777f565e ---> f41f9b6ad7d0 Removing intermediate container 9bc9777f565e Successfully built f41f9b6ad7d0 $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE tommy351/my-server latest f41f9b6ad7d0 6 seconds ago 3.939 MB
  2. Run $ docker run -p 4000:4000 -d tommy351/my-server 9eb06be69a532974e811aa89fdf44805fe63616e684c5c38e7fc 7d766b43dc50

    $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9eb06be69a53 tommy351/my-server "/app" 21 seconds ago Up 20 seconds 0.0.0.0:4000->4000/tcp fervent_heyrovsky $ curl http://localhost:4000 Hello world
  3. Push & Pull $ docker push tommy351/my-server The push refers

    to a repository [docker.io/tommy351/my-server] 8413560c067f: Pushed latest: digest: sha256:becf447f4dc2a950a10330a86d42209ed42c3a4f7d3636fd50cdd5eeaf3589 52 size: 528 $ docker pull tommy351/my-server Using default tag: latest latest: Pulling from tommy351/my-server 432847f70861: Already exists Digest: sha256:becf447f4dc2a950a10330a86d42209ed42c3a4f7d3636fd50cdd5eeaf3589 52 Status: Downloaded newer image for tommy351/my-server:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE tommy351/my-server latest f41f9b6ad7d0 2 minutes ago 3.939 MB
  4. 功能 • 處理理多機之間的關係 • 健康檢查 • ⾃自動⽔水平擴展 • 負載平衡 •

    漸進更更新(Rolling update) • 服務探索 • 設定管理理
  5. kubectl 安裝 Kubernetes 的管理理⼯工具。 透過 gcloud 安裝: https://cloud.google.com/sdk/downloads $ curl

    https://sdk.cloud.google.com | bash $ exec -l $SHELL $ gcloud components install kubectl 從 binary 安裝: https://coreos.com/kubernetes/docs/latest/configure-kubectl.html $ curl -O https://storage.googleapis.com/kubernetes- release/release/v1.3.6/bin/darwin/amd64/kubectl $ chmod +x kubectl $ mv kubectl /usr/local/bin/kubectl
  6. Hello World $ kubectl run my-server --image tommy351/my-server --port 4000

    deployment "my-server" created $ kubectl get deployment NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE my-server 1 1 1 1 17s $ kubectl get replicaset NAME DESIRED CURRENT AGE my-server-1549122061 1 1 20s $ kubectl get pod NAME READY STATUS RESTARTS AGE my-server-1549122061-9io6v 1/1 Running 0 23s $ kubectl expose deployment my-server --type NodePort service "my-server" exposed $ kubectl get service NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes 10.0.0.1 <none> 443/TCP 22m my-server 10.0.0.133 <nodes> 4000/TCP 5s $ curl $(minikube service my-server --url) Hello world
  7. 剛剛做了了什什麼? • kubectl run • 建立 Deployment → ReplicaSet →

    Pod • kubectl expose • 建立 Service • 暴暴露服務給外界存取
  8. 常⽤用指令 建立資源 $ kubectl create -f <filename> 顯⽰示資源列列表,type 可以是 pod,

    rc, service, etc. $ kubectl get <type> 取得單⼀一資源的資訊 $ kubectl get <type> <name> 刪除單⼀一資源 $ kubectl delete <type> <name> $ kubectl delete -f <filename> 在 pod 裡執⾏行行指令(相當於 docker exec) $ kubectl exec -it <pod> <command>
  9. 常⽤用指令 顯⽰示 pod 紀錄(相當於 docker logs) $ kubectl logs <pod>

    更更新資源 $ kubectl apply -f <filename> 顯⽰示 kubernetes 的所有事件 $ kubectl get events 開啟 Kubernetes proxy,預設在 localhost:8001, localhost:8001/ui 是 dashboard $ kubectl proxy 連接埠轉發(e.g. kubectl port-forward postgres 5433:5432) $ kubectl port-forward <pod> <local port>:<remote port>
  10. Pod • ⼀一個以上容器的集合 • Kubernetes 中基本的執⾏行行單位 • 每個 Pod 都會配⼀一個

    Cluster IP • 死掉的話不會重啟,必須透過 Replication controller 或 Replica set 管理理
  11. Pod apiVersion: v1 kind: Pod metadata: name: my-server labels: name:

    my-server spec: containers: - name: my-server image: tommy351/my-server ports: - containerPort: 4000
  12. Replication Controller • 管理理 Pod 的⽣生命週期 • 確保指定數量量的 Pod 在執⾏行行

    https://coreos.com/kubernetes/docs/latest/replication-controller.html
  13. Replication Controller apiVersion: v1 kind: ReplicationController metadata: name: my-server spec:

    replicas: 2 selector: name: my-server template: metadata: name: my-server labels: name: my-server spec: containers: - name: my-server image: tommy351/my-server ports: - containerPort: 4000 和剛剛的 Pod 內容⼀一樣 Pod 數量量 Selector 會選中 Label 符合的 Pod
  14. Service • 三種服務類型: • ClusterIP • 預設的服務類型,只有 Cluster 內部能存取 •

    NodePort • 暴暴露到某個 port • LoadBalancer • 暴暴露到外部 IP(需要雲端服務配合)
  15. Service apiVersion: v1 kind: Service metadata: name: my-server spec: type:

    NodePort ports: - port: 80 targetPort: 4000 selector: name: my-server 透過 Pod labels 選擇指定的 Pod 4000 (pod) → 80 (service)
  16. 服務探索 • Kubernetes 提供了了兩兩種⽅方式讓 Cluster 內部的 Pod 可 以互相找到對⽅方 •

    DNS • Kubernetes 內建了了 kube-dns,可以透過 Service name 存取 • 環境變數
  17. 服務探索 例例:有⼀一個名為 redis 的服務 DNS redis:6379 環境變數 REDIS_SERVICE_HOST=10.0.0.11 REDIS_SERVICE_PORT=6379 REDIS_PORT=tcp://10.0.0.11:6379

    REDIS_PORT_6379_TCP=tcp://10.0.0.11:6379 REDIS_PORT_6379_TCP_PROTO=tcp REDIS_PORT_6379_TCP_PORT=6379 REDIS_PORT_6379_TCP_ADDR=10.0.0.11
  18. 資料持久化 • Container 內的資料必須存在外部,否則 Container 終 ⽌止後就會被刪除 • emptyDir •

    Pod 啟動時分配空間,終⽌止後即被刪除 • hostPath • 掛載主機的路路徑
  19. 資料持久化 • gcePersistentDisk, awsElasticBlockStore, AzureFileVolume, AzureDiskVolume • GCE, AWS, Azure

    提供的磁碟 • nfs • persistentVolumeClaim • http://kubernetes.io/docs/user-guide/volumes/
  20. 資料持久化 apiVersion: v1 kind: Pod metadata: name: redis labels: name:

    redis spec: containers: - name: redis image: redis:3.2 ports: - containerPort: 6379 volumeMounts: - mountPath: /data name: data volumes: - name: data emptyDir: {}
  21. 設定管理理 • 環境變數 • ConfigMap • Secret • 利利⽤用 ConfigMap

    和 Secret 的⽅方式: • 掛載磁碟 • 環境變數
  22. 環境變數 apiVersion: v1 kind: Pod metadata: name: my-server labels: name:

    my-server spec: containers: - name: my-server image: tommy351/my-server ports: - containerPort: 4000 env: - name: REDIS_ADDRESS value: redis:6379 - name: SERVER_HOST value: :4000 REDIS_ADDRESS=“redis:6379” SERVER_HOST=“:4000”
  23. Secret apiVersion: v1 kind: Secret metadata: name: redis type: Opaque

    data: username: YWRtaW4= password: cGFzcw== data 必須經過 base64 編碼 password=base64(“pass”) username=base64(“admin”)
  24. 掛載 ConfigMap / Secret apiVersion: v1 kind: Pod metadata: name:

    redis labels: name: redis spec: containers: - name: redis image: redis:3.2 ports: - containerPort: 6379 volumeMounts: - mountPath: /usr/local/etc/redis name: config - mountPath: /srv/redis/secret name: secret volumes: - name: config configMap: name: redis - name: secret secret: secretName: redis /usr/local/etc/redis/redis.conf maxmemory 2mb maxmemorypolicy allkeyslru /srv/redis/secret/username admin /srv/redis/secret/password pass
  25. 從 ConfigMap / Secret 設定環境變數 apiVersion: v1 kind: Pod metadata:

    name: redis labels: name: redis spec: containers: - name: redis image: redis:3.2 ports: - containerPort: 6379 env: - name: REDIS_CONF valueFrom: configMapKeyRef: name: redis key: redisconf - name: REDIS_USERNAME valueFrom: secretKeyRef: name: redis key: username - name: REDIS_PASSWORD valueFrom: secretKeyRef: name: redis key: password REDIS_CONF maxmemory 2mb maxmemorypolicy allkeyslru REDIS_USERNAME admin REDIS_PASSWORD pass
  26. 健康檢查 • 檢查 Pod 是否正常執⾏行行 • 兩兩種檢查時期: • livenessProbe •

    檢查 Pod 是否還活著,每隔⼀一段時間就會執⾏行行 • readinessProbe • 確保 Pod 已經開啟並能正常運作,在 Pod 進入 Running 狀狀態前執⾏行行
  27. 健康檢查 • 三種檢查⽅方式: • exec • 執⾏行行指令並檢查回傳值是否為 0 • httpGet

    • 發送 HTTP 請求,並檢查回傳狀狀態為 2xx • tcpSocket • 確保 TCP socket 開啟
  28. 健康檢查 apiVersion: v1 kind: Pod metadata: name: my-server labels: name:

    my-server spec: containers: - name: my-server image: tommy351/my-server ports: - containerPort: 4000 livenessProbe: initialDelaySeconds: 15 periodSeconds: 10 httpGet: path: / port: 4000 timeoutSeconds: 5 Pod 啟動 15 秒後 每隔 10 秒 戳 http://localhost:4000/ 如果回傳狀狀態不是 2xx 或超過 5 秒沒有回應 即判斷 Pod 不健康
  29. Rolling Update • 從舊的 image 漸進更更新到新的 image • 建立新的 Replication

    controller • ⽤用新的 image 開啟 container 並漸漸消滅舊的 container • 完成後重新命名新的 Replication controller 並消滅 舊的
  30. Rolling Update $ kubectl rolling-update my-server —image=tommy351/my-server:v2 Created my-server-bc33bf3389402cd633ec4573695db4dc Scaling

    up my-server-bc33bf3389402cd633ec4573695db4dc from 0 to 2, scaling down my-server from 2 to 0 (keep 2 pods available, don't exceed 3 pods) Scaling my-server-bc33bf3389402cd633ec4573695db4dc up to 1 Scaling my-server down to 1 Scaling my-server-bc33bf3389402cd633ec4573695db4dc up to 2 Scaling my-server down to 0 Update succeeded. Deleting old controller: my-server Renaming my-server-bc33bf3389402cd633ec4573695db4dc to my-server replicationcontroller "my-server" rolling updated $ kubectl get rc -o wide NAME DESIRED CURRENT AGE CONTAINER(S) IMAGE(S) SELECTOR my-server 2 2 23s my-server tommy351/my-server:v2 deployment=bc33bf3389402cd633ec4573695db4dc,name=my-server
  31. 資源管理理 • 可設定 CPU、記憶體限制 • requests • 必須有⾜足夠資源才能啟動 Pod,否則會在 Pending

    狀狀態等待 • limits • 超過資源上限的話,會使 Pod 終⽌止 • 如果沒有設定 requests 的話,requests = limit
  32. 資源管理理 apiVersion: v1 kind: Pod metadata: name: my-server labels: name:

    my-server spec: containers: - name: my-server image: tommy351/my-server ports: - containerPort: 4000 resources: requests: cpu: 200m memory: 100Mi limits: cpu: 500m memory: 200Mi requests.cpu = 0.2 core requests.memory = 100MB limits.cpu = 0.5 core limits.memory = 200MB
  33. ⼿手動擴展 $ kubectl scale rc my-server —replicas=6 replicationcontroller "my-server" scaled

    $ kubectl get rc NAME DESIRED CURRENT AGE my-server 6 6 1m $ kubectl get pod NAME READY STATUS RESTARTS AGE my-server-54m5f 1/1 Running 0 26s my-server-9qxko 1/1 Running 0 26s my-server-e9bch 1/1 Running 0 26s my-server-tzjlm 1/1 Running 0 26s my-server-yo6j8 1/1 Running 0 1m my-server-zeh6e 1/1 Running 0 1m
  34. HorizontalPodAutoscaler apiVersion: extensions/v1beta1 kind: HorizontalPodAutoscaler metadata: name: my-server spec: scaleRef:

    kind: ReplicationController name: my-server subresource: scale minReplicas: 1 maxReplicas: 10 cpuUtilization: targetPercentage: 50
  35. Google Container Engine • 如果你懶懶得⾃自⼰己架 Kubernetes cluster 的話,Google Container Engine

    ⼤大概是最輕鬆簡單的 solution • Load balancer • Cloud Logging • Private Docker Registry • Cloud Monitoring
  36. Ingress • ⾃自動在 Google Cloud 上建立 Load balancer • 必須使⽤用

    NodePort service • Google Cloud 的 Load balancer 也有健康檢查,但是 和 Kubernetes 不互通,要另外設定 • 必須暴暴露 30000-32767 TCP port(NodePort 的範圍) 才能讓 Google Cloud 健康檢查
  37. Ingress apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules:

    - host: foo.bar.com http: paths: - path: /foo backend: serviceName: s1 servicePort: 80 - path: /bar backend: serviceName: s2 servicePort: 80