kubernetes入門實踐

k8s中文文檔

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

me的環境

  • 操做系統:centos7
  • docker:1.12.6

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

還慌?那就直接用網頁在線版的kubernetsmysql

kubernets單機版安裝部署

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

安裝流程,切換成root

 
# 關閉centos自帶的防火牆
$ sudo systemctl disable firewalld
$ sudo systemctl stop firewalld
# 安裝etcd和kubernetes軟件(會自動安裝docker)
$ sudo yum install -y etcd kubernetes

修改兩處配置

  • Docker配置文件/etc/sysconfig/docker, OPTIONS=’–selinux-enabled=false –insecure-registry gcr.io’
 
# Modify these options if you want to change the way the docker daemon runs
OPTIONS='--selinux-enabled=false --insecure-registry gcr.io'
if [ -z "${DOCKER_CERT_PATH}" ]; then
DOCKER_CERT_PATH=/etc/docker
fi
# Do not add registries in this file anymore. Use /etc/containers/registries.conf
# from the atomic-registries package.
#
# docker-latest daemon can be used by starting the docker-latest unitfile.
# To use docker-latest client, uncomment below lines
#DOCKERBINARY=/usr/bin/docker-latest
#DOCKERDBINARY=/usr/bin/dockerd-latest
#DOCKER_CONTAINERD_BINARY=/usr/bin/docker-containerd-latest
#DOCKER_CONTAINERD_SHIM_BINARY=/usr/bin/docker-containerd-shim-latest
  • Kubernetes apiservce配置文件/etc/kubernetes/apiserver,把–admission_control參數鐘的ServiceAccount刪除
 
###
# kubernetes system config
#
# The following values are used to configure the kube-apiserver
#
# The address on the local server to listen to.
KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0"
# The port on the local server to listen on.
# KUBE_API_PORT="--port=8080"
# Port minions listen on
# KUBELET_PORT="--kubelet-port=10250"
# Comma separated list of nodes in the etcd cluster
KUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:2379"
# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"
# default admission control policies
KUBE_ADMISSION_CONTROL="--admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ResourceQuota"
# Add your own!
KUBE_API_ARGS=""

啓動全部服務

 
# 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服務nginx

       
    $ kubectl run my-nginx --image=nginx --port= 80
    $ kubectl get pod # 查看pod

發現pod狀態不管多久都是處於pending。READY字段一直是0/1,服務部署失敗的緣由是」中國牆「的問題致使沒法下載pod啓動時須要的谷歌鏡像,因此咱們得間接的建立所需的鏡像。git

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

  • 建立gcr.io/google_containers/pause-amd64:3.0鏡像sql

       
    $ 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

 
# 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文件來建立服務shell

       
    # 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
  • 啓動管理服務centos

       
    # 根據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

宿主主機內訪問該服務

 
$ kubectl describe service/my-nginx
# 顯示的字段有Endpoints: 172.17.0.2:80
$ curl 172.17. 0.2. 80

Alt text

同網段的機器訪問該服務

 
$ curl 192.168. 33.101: 32589

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的更新回滾

Alt text

 
$ 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}

報錯

 
$ 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鍵來空格
$ sudo kubectl create -f mysql-rc.yaml
error: error validating "mysql-rc.yaml": error validating data: [found invalid field app for v1.ObjectMeta, found invalid field value for v1.Container]; if you choose to ignore these errors, turn validation off with --validate=false
---------------------
# kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
default my-nginx- 379829228-b796w 1/ 1 Running 0 12m
kube-system kubernetes-dashboard- 2397086622- 46tvx 0/ 1 ContainerCreating 0 8s
[root@node01 ~] # kubectl logs -f kubernetes-dashboard-2397086622-46tvx --namespace=kube-system
Using HTTP port: 9090
Using apiserver-host location: http:// 127.0. 0.1: 8080
Creating API server client for http:// 127.0. 0.1: 8080
Error while initializing connection to Kubernetes apiserver. This most likely means that the cluster is misconfigured (e.g., it has invalid apiserver certificates or service accounts configuration) or the --apiserver-host param points to a server that does not exist. Reason: Get http:// 127.0. 0.1: 8080/version: dial tcp 127.0. 0.1: 8080: getsockopt: connection refused
Refer to the troubleshooting guide for more information: https://github.com/kubernetes/dashboard/blob/master/docs/user-guide/troubleshooting.md
咱們最好不要越過RC而直接建立Pod,由於Replication Controller會經過RC管理Pod副本。實現自動建立、補足、替換、刪除Pod副本,大大提升系統的容災能力
  • 從新調度(Rescheduling)
  • 彈性伸縮(Scaling)
  • 滾動更新(Rolling Updates)
相關文章
相關標籤/搜索