1. 程式人生 > >(kubernetes)k8s入門、單機版安裝、kuberctl指令、k8s服務例項。

(kubernetes)k8s入門、單機版安裝、kuberctl指令、k8s服務例項。

k8s中文文件

  • k8s概念比較多,有什麼概念的疑惑的推薦看k8s中文文件。

me的環境

  • 作業系統:centos7
  • docker:1.12.6

環境跟me的不一致?不要慌,基本大部分操作都是行的通的。

還慌?那就直接用網頁線上版的kubernets

kubernets單機版安裝部署

kubernetes部署算是有一定門檻的。為了不從入門到放棄,推薦一開始安裝單機版作為入門熟悉kubectl指令、瞭解工作原理。

  • 安裝流程,切換成root

    1.關閉centos自帶的防火牆
    
    # systemctl disable firewalld
    
    
    # systemctl stop firewalld 
    2.安裝etcd和kubernetes軟體(會自動安裝docker) # yum install -y etcd kubernetes
  • 修改兩處配置

    1. Docker配置檔案/etc/sysconfig/docker, OPTIONS=’–selinux-enabled=false –insecure-registry gcr.io’

    這裡寫圖片描述

    1. Kubernetes apiservce配置檔案/etc/kubernetes/apiserver,把–admission_control引數鐘的ServiceAccount刪除

    這裡寫圖片描述

啟動所有服務

# systemctl start etcd
# systemctl start docker
# systemctl start kube-apiserver # systemctl start kube-controller-manager # systemctl start kube-scheduler # systemctl start kubelet # systemctl start kube-proxy

初入門小例項

  • 部署nginx服務

    $ kubectl run my-nginx --image=nginx --port=80
    $ kubectl get pod  # 檢視pod

    發現pod狀態無論多久都是處於pending。READY欄位一直是0/1,服務部署失敗的原因是”中國牆“的問題導致無法下載pod啟動時需要的谷歌映象,所以我們得間接的建立所需的映象。

    補充: Pending狀態表示API Server已經建立Pod,但Pod內還有一個或者多個容器沒有建立,或者正在下載映象的過程。詳細的參考Pod宣告週期和重啟策略

  • 建立gcr.io/google_containers/pause-amd64:3.0映象

    $ docker pull googlecontainer/pause-amd64:3.0
    $ docker tag googlecontainer/pause-amd64:3.0 gcr.io/google_containers/pause-amd64:3.0

kubernets指令

  • 例項流程
# 檢視版本
$ kubectl  version
Client Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"269f928217957e7126dc87e6adfa82242bfe5b1e", GitTreeState:"clean", BuildDate:"2017-07-03T15:31:10Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"5", GitVersion:"v1.5.2", GitCommit:"269f928217957e7126dc87e6adfa82242bfe5b1e", GitTreeState:"clean", BuildDate:"2017-07-03T15:31:10Z", GoVersion:"go1.7.4", Compiler:"gc", Platform:"linux/amd64"}

# 顯示叢集資訊
$ kubectl cluster-info
Kubernetes master is running at http://localhost:8080
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# 檢視叢集中有幾個Node
$ kubectl get nodes
NAME        STATUS    AGE
127.0.0.1   Ready     18h

# 執行一個映象
$ kubectl run my-nginx --image=nginx --replicas=2 --port=80
deployment "my-nginx" created

# 檢視pod
$ kubectl  get pods
NAME                       READY     STATUS              RESTARTS   AGE
my-nginx-379829228-cwlbb   0/1       ContainerCreating   0          20s
my-nginx-379829228-czk6w   1/1       Running             0          20s

# 檢視服務詳情資訊
$ kubectl  describe pod my-nginx-379829228-cwlbb

# 檢視已部署
$ kubectl  get deployments
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
my-nginx   2         2         2            2           3m

# 刪除pod
$ kubectl delete pod my-nginx-379829228-cwlbb
pod "my-nginx-379829228-cwlbb" deleted

# 再次檢視pod,發現由於replicas機制,pod又生成一個新的
$ kubectl  get pods
NAME                       READY     STATUS              RESTARTS   AGE
my-nginx-379829228-czk6w   1/1       Running             0          11m
my-nginx-379829228-gjd7d   0/1       ContainerCreating   0          5s

# 刪除部署的my-nginx服務。徹底刪除pod
$ kubectl delete deployment my-nginx
deployment "my-nginx" deleted

對比docker命令

k8s的學習路線基本都是從docker[容器]到k8s的,因此兩個對比理解有助於記憶

# docker run
$ docker run -d -e DOMAIN=cluster --name my-nginx -p 80:80 nginx
$ kubectl run my-nginx --image=nginx --port=80 --env="DOMAIN=cluster"

# docker ps 
$ docker ps 
$ kubectl get pods

# docker exec
$ docker exec [容器id] ls
$ kubectl exec [pod_id] ls

# docker exec 互動式
$ docker exec -it [容器id] /bin/sh
$ kubectl exec -it [pod_id] -- /bin/sh

# docker info
$ docker info 
$ kubectl cluster-info

重要名詞

名詞 翻譯
Namespace 名稱空間
Endpoint 服務端點
Controller Manager 管理控制中心
Replication 副本控制器

yaml檔案管理服務

  • 用yaml檔案來建立服務

    
    # vi nginx.yaml
    
    
    piVersion: extensions/v1beta1
    kind: Deployment
    metadata:
    name: my-nginx
    spec:
    replicas: 3
    template:
      metadata:
        labels:
          app: nginx
      spec:
        containers:
        - name: nginx
          image: nginx:1.7.9
          ports:
          - containerPort: 80
  • 啟動管理服務

    
    # 根據yaml檔案建立服務
    
    $ kubectl create -f nginx.yaml 
    deployment "my-nginx" created
    
    # 檢視deployment
    
    $ kubectl get deployments
    NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
    my-nginx   3         3         3            3           6s
    
    # 檢視Pod
    
    $ kubectl get pod
    NAME                        READY     STATUS    RESTARTS   AGE
    my-nginx-4087004473-dtrjp   1/1       Running   0          7s
    my-nginx-4087004473-jz80p   1/1       Running   0          7s
    my-nginx-4087004473-wh576   1/1       Running   0          7s
    
    # 根據yaml檔案刪除服務
    
    $ kubectl delete -f nginx.yaml 
    deployment "my-nginx" deleted
    
    $ kubectl get pod
    No resources found.
    $ kubectl get deployment
    No resources found.

Service

  • 到此,我們部署一個nginx服務

    $ kubectl run my-nginx --image=nginx --port=80
    
    # 建立一個service 且將其暴露到叢集外可供訪問
    
    $ kubectl expose deployment/my-nginx --type="NodePort" --port 80
    service "my-nginx" exposed
    
    # 此時service列表多個my-nginx服務
    
    $ kubectl get services
    NAME         CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
    kubernetes   10.254.0.1       <none>        443/TCP        7d
    my-nginx     10.254.255.103   <nodes>       80:32589/TCP   7s

    宿主主機內訪問該服務

    這裡寫圖片描述

    同網段的機器訪問該服務

    這裡寫圖片描述

deployments

# 執行nginx映象
$ kubectl run my-nginx --image=nginx --port=80
# 互動式 shell 的方式執行 pod
$ kubectl run -i --tty my-nginx --image=nginx --port=80 -- sh
# 連結到執行中的容器
$ kubectl attach my-nginx-532658988-10kxd -i

# 檢視deployment
$ kubectl get deployments
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
my-nginx   1         1         1            1           25m
# 擴充套件10個副本
$ kubectl scale deployment my-nginx --replicas=10
deployment "my-nginx" scaled
$ kubectl scale  deployment/my-nginx --replicas=10 # 作用效果等同上一條命令 
deployment "my-nginx" scaled
# 再次顯示deployment
$ kubectl get deployments
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
my-nginx   10        10        10           1           26m
$ kubectl get pods
NAME                       READY     STATUS    RESTARTS   AGE
my-nginx-379829228-38hkg   1/1       Running   0          5m
my-nginx-379829228-7j15l   1/1       Running   0          31m
my-nginx-379829228-c8mt3   1/1       Running   0          5m
my-nginx-379829228-f6mm8   1/1       Running   0          5m
my-nginx-379829228-q1rj0   1/1       Running   0          5m
my-nginx-379829228-qg7lf   1/1       Running   0          5m
my-nginx-379829228-rjfbq   1/1       Running   0          5m
my-nginx-379829228-v581r   1/1       Running   0          5m
my-nginx-379829228-wh49w   1/1       Running   0          5m
my-nginx-379829228-wpn98   1/1       Running   0          5m

# 縮擴到1個副本
$ kubectl scale  deployment/my-nginx --replicas=1
deployment "my-nginx" scaled
$ kubectl scale deployment my-nginx --replicas=1   # 作用效果等同上一條命令

deployment的更新回滾

這裡寫圖片描述

$ kubectl create -f nginx.yaml
$ kubectl get pod
NAME                        READY     STATUS    RESTARTS   AGE
my-nginx-4087004473-4xj74   1/1       Running   0          3m
my-nginx-4087004473-jkptq   1/1       Running   0          3m
my-nginx-4087004473-m55s1   1/1       Running   0          3m
$ kubectl get deployment
NAME       DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
my-nginx   3         3         3            3           4m
# 更新應用的映象從1.7.9版本——>1.9.1
$ kubectl set image deployment/my-nginx nginx=nginx:1.9.1
deployment "my-nginx" image updated
# 確認是否更新成功
$ kubectl rollout status deployment/my-nginx
deployment "my-nginx" successfully rolled out
# 回滾到上一代版本
$ kubectl rollout undo deployment/my-nginx
deployment "my-nginx" rolled back

ConfigMap-容器應用的配置管理

應用部署的一個最佳實踐是將應用所需配置資訊和程式進行分離,一則程式可以更好的複用,二則能靈活的更改配置從而實現其他功能。

使用configMap替代環境變數

以yaml檔案方式建立ConfigMap

# vi special-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  special.how: very
  special.type: charm
# vi env-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: env-config
  namespace: default
data:
  log_level: INFO

可以在Pod中這樣使用ConfigMap

# vi configMap.yaml

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY   #定義環境變數名稱
          valueFrom:       #key"special.how"對應的值
            configMapKeyRef:
              name: special-config #環境變數的值
              key: special.how
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: special-config
              key: special.type
  restartPolicy: Never

啟動等一系列操作

$ kubectl create -f special-config.yaml
configmap "special-config" created
$ kubectl create -f env-config.yaml
configmap "env-config" created
# 檢視ConfigMap
$ kubectl get configmaps
NAME             DATA      AGE
env-config       1         38m
special-config   2         39m
# 讓我們看一下建立的ConfigMap
$  kubectl describe configmap env-config
Name:       env-config
Namespace:  default
Labels:     <none>
Annotations:    <none>

Data
====
log_level:  4 bytes

# 檢視ConfigMap鍵的值
$ kubectl get configmaps env-config -o yaml
apiVersion: v1
data:
  log_level: INFO
kind: ConfigMap
metadata:
  creationTimestamp: 2017-11-30T07:29:49Z
  name: env-config
  namespace: default
  resourceVersion: "285268"
  selfLink: /api/v1/namespaces/default/configmaps/env-config
  uid: 3f473adf-d5a0-11e7-9830-0800275ae9e7

$ kubectl create -f configMap.yaml
pod "dapi-test-pod" created
# 檢視pod,狀態ContainerCreating
$ kubectl get pod
NAME            READY     STATUS              RESTARTS   AGE
dapi-test-pod   0/1       ContainerCreating   0          3s
# 隔一段時間再檢視pod,發現並沒有返回什麼
$  kubectl get pod
# 顯示所有的許可權檢視pod
$ kubectl get pod --show-all
NAME            READY     STATUS      RESTARTS   AGE
dapi-test-pod   0/1       Completed   0          1m
# 檢視詳情
$ kubectl describe pod dapi-test-pod
Name:       dapi-test-pod
Namespace:  default
Node:       127.0.0.1/127.0.0.1
Start Time: Thu, 30 Nov 2017 15:32:00 +0800
Labels:     <none>
Status:     Succeeded
IP:     
Controllers:    <none>
Containers:
  test-container:
    Container ID:   docker://1ba533f43ee60c02e03dafb7bcb8495fc12264aaab229872df0b289a3c1b9976
    Image:      nginx
    Image ID:       docker-pullable://docker.io/nginx@sha256:b81f317384d7388708a498555c28a7cce778a8f291d90021208b3eba3fe74887
    Port:       
    Command:
      /bin/sh
      -c
      env
    State:      Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Thu, 30 Nov 2017 15:32:25 +0800
      Finished:     Thu, 30 Nov 2017 15:32:25 +0800
    Ready:      False
    Restart Count:  0
    Volume Mounts:  <none>
    Environment Variables:
      SPECIAL_LEVEL_KEY:    <set to the key 'special.how' of config map 'special-config'>
      SPECIAL_TYPE_KEY:     <set to the key 'special.type' of config map 'special-config'>
Conditions:
  Type      Status
  Initialized   True 
  Ready     False 
  PodScheduled  True 
No volumes.
QoS Class:  BestEffort
Tolerations:    <none>
Events:
  FirstSeen LastSeen    Count   From            SubObjectPath           Type        Reason          Message
  --------- --------    -----   ----            -------------           --------    ------          -------
  3m        3m      1   {default-scheduler }                    Normal      Scheduled       Successfully assigned dapi-test-pod to 127.0.0.1
  3m        3m      1   {kubelet 127.0.0.1} spec.containers{test-container} Normal      Pulling         pulling image "nginx"
  3m        2m      2   {kubelet 127.0.0.1}                 Warning     MissingClusterDNS   kubelet does not have ClusterDNS IP configured and cannot create Pod using "ClusterFirst" policy. Falling back to DNSDefault policy.
  2m        2m      1   {kubelet 127.0.0.1} spec.containers{test-container} Normal      Pulled          Successfully pulled image "nginx"
  2m        2m      1   {kubelet 127.0.0.1} spec.containers{test-container} Normal      Created         Created container with docker id 1ba533f43ee6; Security:[seccomp=unconfined]
  2m        2m      1   {kubelet 127.0.0.1} spec.containers{test-container} Normal      Started         Started container with docker id 1ba533f43ee6
# 可知container started 成功,進一步檢視日誌
$ docker logs 1ba
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.254.0.1:443
MY_SERVICE_PORT_80_TCP=tcp://10.254.110.249:80
MY_SERVICE_PORT_443_TCP_ADDR=10.254.110.249
HOSTNAME=dapi-test-pod
MY_SERVICE_PORT_443_TCP_PORT=443
HOME=/root
MY_SERVICE_PORT_443_TCP_PROTO=tcp
MY_SERVICE_SERVICE_PORT_HTTP=80
SPECIAL_TYPE_KEY=charm
MY_SERVICE_SERVICE_PORT_HTTPS=443
MY_SERVICE_PORT_443_TCP=tcp://10.254.110.249:443
MY_SERVICE_SERVICE_HOST=10.254.110.249
KUBERNETES_PORT_443_TCP_ADDR=10.254.0.1
NGINX_VERSION=1.13.7-1~stretch
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
NJS_VERSION=1.13.7.0.1.15-1~stretch
KUBERNETES_PORT_443_TCP_PROTO=tcp
MY_SERVICE_SERVICE_PORT=80
MY_SERVICE_PORT=tcp://10.254.110.249:80
SPECIAL_LEVEL_KEY=very
MY_SERVICE_PORT_80_TCP_ADDR=10.254.110.249
KUBERNETES_PORT_443_TCP=tcp://10.254.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_SERVICE_HOST=10.254.0.1
MY_SERVICE_PORT_80_TCP_PORT=80
PWD=/
MY_SERVICE_PORT_80_TCP_PROTO=tcp

ConfigMap的限制條件

  • ConfigMap必須在Pod之前建立才能被使用。
  • ConfigMap可以定義其屬於哪個Namspece,只有在同一個Namespace中的pod才能引用。

刪除Pod

  • 有時候deployment、rs、rc、services都為0,但是Pod確存在著。則重啟kubelet服務即可。
$ systemctl restart kubelet

補充

# 列出當前節點名
kubectl get node
NAME        STATUS    AGE
127.0.0.1   Ready     6d
# 已知當前節點名為127.0.0.1,用如下命令即可獲得該節點上所有執行節點
$ curl localhost:8080/api/v1/proxy/nodes/127.0.0.1/pods
{"kind":"PodList","apiVersion":"v1","metadata":{},"items":null}
我們最好不要越過RC而直接建立Pod,因為Replication Controller會通過RC管理Pod副本。實現自動建立、補足、替換、刪除Pod副本,大大提高系統的容災能力
  • 重新排程(Rescheduling)
  • 彈性伸縮(Scaling)
  • 滾動更新(Rolling Updates)

報錯

$ sudo kubectl create -f file.yaml
YAML error: found character that cannot start any token 
# or
error:yaml: line 15: found a tab character that violate indentation

#file.yaml不可用tab鍵來空格