環境跟me的不一致?不要慌,基本大部分操做都是行的通的。node
還慌?那就直接用網頁在線版的kubernets吧mysql
kubernetes部署算是有必定門檻的。爲了避免從入門到放棄,推薦一開始安裝單機版做爲入門熟悉kubectl指令、瞭解工做原理。linux
# 關閉centos自帶的防火牆$ sudo systemctl disable firewalld$ sudo systemctl stop firewalld# 安裝etcd和kubernetes軟件(會自動安裝docker)$ sudo yum install -y etcd kubernetes
# Modify these options if you want to change the way the docker daemon runsOPTIONS='--selinux-enabled=false --insecure-registry gcr.io'if [ -z "${DOCKER_CERT_PATH}" ]; thenDOCKER_CERT_PATH=/etc/dockerfi# 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 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 clusterKUBE_ETCD_SERVERS="--etcd-servers=http://127.0.0.1:2379"# Address range to use for servicesKUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=10.254.0.0/16"# default admission control policiesKUBE_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
# 查看版本$ kubectl versionClient 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-infoKubernetes master is running at http://localhost: 8080To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.# 查看集羣中有幾個Node$ kubectl get nodesNAME STATUS AGE127.0. 0.1 Ready 18h# 運行一個鏡像$ kubectl run my-nginx --image=nginx --replicas= 2 --port= 80deployment "my-nginx" created# 查看pod$ kubectl get podsNAME READY STATUS RESTARTS AGEmy-nginx- 379829228-cwlbb 0/ 1 ContainerCreating 0 20smy-nginx- 379829228-czk6w 1/ 1 Running 0 20s# 查看服務詳情信息$ kubectl describe pod my-nginx- 379829228-cwlbb# 查看已部署$ kubectl get deploymentsNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEmy-nginx 2 2 2 2 3m# 刪除pod$ kubectl delete pod my-nginx- 379829228-cwlbbpod "my-nginx-379829228-cwlbb" deleted# 再次查看pod,發現因爲replicas機制,pod又生成一個新的$ kubectl get podsNAME READY STATUS RESTARTS AGEmy-nginx- 379829228-czk6w 1/ 1 Running 0 11mmy-nginx- 379829228-gjd7d 0/ 1 ContainerCreating 0 5s# 刪除部署的my-nginx服務。完全刪除pod$ kubectl delete deployment my-nginxdeployment "my-nginx" deleted
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文件來建立服務shell
# vi nginx.yamlpiVersion: extensions/v1beta1kind: Deploymentmetadata:name: my-nginxspec:replicas: 3template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80
啓動管理服務centos
# 根據yaml文件建立服務$ kubectl create -f nginx.yamldeployment "my-nginx" created# 查看deployment$ kubectl get deploymentsNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEmy-nginx 3 3 3 3 6s# 查看Pod$ kubectl get podNAME READY STATUS RESTARTS AGEmy-nginx- 4087004473-dtrjp 1/ 1 Running 0 7smy-nginx- 4087004473-jz80p 1/ 1 Running 0 7smy-nginx- 4087004473-wh576 1/ 1 Running 0 7s# 根據yaml文件刪除服務$ kubectl delete -f nginx.yamldeployment "my-nginx" deleted$ kubectl get podNo resources found.$ kubectl get deploymentNo resources found.
到此,咱們部署一個nginx服務
$ kubectl run my-nginx --image=nginx --port= 80# 建立一個service 且將其暴露到集羣外可供訪問$ kubectl expose deployment/my-nginx --type= "NodePort" --port 80service "my-nginx" exposed# 此時service列表多個my-nginx服務$ kubectl get servicesNAME CLUSTER-IP EXTERNAL-IP PORT(S) AGEkubernetes 10.254. 0.1 <none> 443/TCP 7dmy-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
同網段的機器訪問該服務
$ curl 192.168. 33.101: 32589
# 運行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 deploymentsNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEmy-nginx 1 1 1 1 25m# 擴展10個副本$ kubectl scale deployment my-nginx --replicas= 10deployment "my-nginx" scaled$ kubectl scale deployment/my-nginx --replicas= 10 # 做用效果等同上一條命令deployment "my-nginx" scaled# 再次顯示deployment$ kubectl get deploymentsNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEmy-nginx 10 10 10 1 26m$ kubectl get podsNAME READY STATUS RESTARTS AGEmy-nginx- 379829228- 38hkg 1/ 1 Running 0 5mmy-nginx- 379829228- 7j15l 1/ 1 Running 0 31mmy-nginx- 379829228-c8mt3 1/ 1 Running 0 5mmy-nginx- 379829228-f6mm8 1/ 1 Running 0 5mmy-nginx- 379829228-q1rj0 1/ 1 Running 0 5mmy-nginx- 379829228-qg7lf 1/ 1 Running 0 5mmy-nginx- 379829228-rjfbq 1/ 1 Running 0 5mmy-nginx- 379829228-v581r 1/ 1 Running 0 5mmy-nginx- 379829228-wh49w 1/ 1 Running 0 5mmy-nginx- 379829228-wpn98 1/ 1 Running 0 5m# 縮擴到1個副本$ kubectl scale deployment/my-nginx --replicas= 1deployment "my-nginx" scaled$ kubectl scale deployment my-nginx --replicas= 1 # 做用效果等同上一條命令
$ kubectl create -f nginx.yaml$ kubectl get podNAME READY STATUS RESTARTS AGEmy-nginx- 4087004473- 4xj74 1/ 1 Running 0 3mmy-nginx- 4087004473-jkptq 1/ 1 Running 0 3mmy-nginx- 4087004473-m55s1 1/ 1 Running 0 3m$ kubectl get deploymentNAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGEmy-nginx 3 3 3 3 4m# 更新應用的鏡像從1.7.9版本——>1.9.1$ kubectl set image deployment/my-nginx nginx=nginx: 1.9. 1deployment "my-nginx" image updated# 確認是否更新成功$ kubectl rollout status deployment/my-nginxdeployment "my-nginx" successfully rolled out# 回滾到上一代版本$ kubectl rollout undo deployment/my-nginxdeployment "my-nginx" rolled back
應用部署的一個最佳實踐是將應用所需配置信息和程序進行分離,一則程序能夠更好的複用,二則能靈活的更改配置從而實現其餘功能。
以yaml文件方式建立ConfigMap
# vi special-config.yamlapiVersion: v1kind: ConfigMapmetadata:name: special-confignamespace: defaultdata:special.how: veryspecial.type: charm
# vi env-config.yamlapiVersion: v1kind: ConfigMapmetadata:name: env-confignamespace: defaultdata:log_level: INFO
能夠在Pod中這樣使用ConfigMap
# vi configMap.yamlapiVersion: v1kind: Podmetadata:name: dapi-test-podspec:containers:- name: test-containerimage: nginxcommand: [ "/bin/sh" , "-c" , "env" ]env:- name: SPECIAL_LEVEL_KEY #定義環境變量名稱valueFrom: #key"special.how"對應的值configMapKeyRef:name: special-config #環境變量的值key: special.how- name: SPECIAL_TYPE_KEYvalueFrom:configMapKeyRef:name: special-configkey: special.typerestartPolicy: Never
啓動等一系列操做
$ kubectl create -f special-config.yamlconfigmap "special-config" created$ kubectl create -f env-config.yamlconfigmap "env-config" created# 查看ConfigMap$ kubectl get configmapsNAME DATA AGEenv-config 1 38mspecial-config 2 39m# 讓咱們看一下建立的ConfigMap$ kubectl describe configmap env-configName: env-configNamespace: defaultLabels: <none>Annotations: <none>Data====log_level: 4 bytes# 查看ConfigMap鍵的值$ kubectl get configmaps env-config -o yamlapiVersion: v1data:log_level: INFOkind: ConfigMapmetadata:creationTimestamp: 2017- 11- 30T07: 29: 49Zname: env-confignamespace: defaultresourceVersion: "285268"selfLink: /api/v1/namespaces/default/configmaps/env-configuid: 3f473adf-d5a0- 11e7- 9830- 0800275ae9e7
$ kubectl create -f configMap.yamlpod "dapi-test-pod" created# 查看pod,狀態ContainerCreating$ kubectl get podNAME READY STATUS RESTARTS AGEdapi-test-pod 0/ 1 ContainerCreating 0 3s# 隔一段時間再查看pod,發現並無返回什麼$ kubectl get pod# 顯示全部的權限查看pod$ kubectl get pod --show-allNAME READY STATUS RESTARTS AGEdapi-test-pod 0/ 1 Completed 0 1m# 查看詳情$ kubectl describe pod dapi-test-podName: dapi-test-podNamespace: defaultNode: 127.0. 0.1/ 127.0. 0.1Start Time: Thu, 30 Nov 2017 15: 32: 00 + 0800Labels: <none>Status: SucceededIP:Controllers: <none>Containers:test-container:Container ID: docker:// 1ba533f43ee60c02e03dafb7bcb8495fc12264aaab229872df0b289a3c1b9976Image: nginxImage ID: docker-pullable://docker.io/nginx@sha256:b81f317384d7388708a498555c28a7cce778a8f291d90021208b3eba3fe74887Port:Command:/bin/sh-cenvState: TerminatedReason: CompletedExit Code: 0Started: Thu, 30 Nov 2017 15: 32: 25 + 0800Finished: Thu, 30 Nov 2017 15: 32: 25 + 0800Ready: FalseRestart Count: 0Volume 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 StatusInitialized TrueReady FalsePodScheduled TrueNo volumes.QoS Class: BestEffortTolerations: <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.13m 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 1baKUBERNETES_SERVICE_PORT= 443KUBERNETES_PORT=tcp:// 10.254. 0.1: 443MY_SERVICE_PORT_80_TCP=tcp:// 10.254. 110.249: 80MY_SERVICE_PORT_443_TCP_ADDR= 10.254. 110.249HOSTNAME=dapi-test-podMY_SERVICE_PORT_443_TCP_PORT= 443HOME=/rootMY_SERVICE_PORT_443_TCP_PROTO=tcpMY_SERVICE_SERVICE_PORT_HTTP= 80SPECIAL_TYPE_KEY=charmMY_SERVICE_SERVICE_PORT_HTTPS= 443MY_SERVICE_PORT_443_TCP=tcp:// 10.254. 110.249: 443MY_SERVICE_SERVICE_HOST= 10.254. 110.249KUBERNETES_PORT_443_TCP_ADDR= 10.254. 0.1NGINX_VERSION= 1.13. 7- 1~stretchPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/binKUBERNETES_PORT_443_TCP_PORT= 443NJS_VERSION= 1.13. 7.0. 1.15- 1~stretchKUBERNETES_PORT_443_TCP_PROTO=tcpMY_SERVICE_SERVICE_PORT= 80MY_SERVICE_PORT=tcp:// 10.254. 110.249: 80SPECIAL_LEVEL_KEY=veryMY_SERVICE_PORT_80_TCP_ADDR= 10.254. 110.249KUBERNETES_PORT_443_TCP=tcp:// 10.254. 0.1: 443KUBERNETES_SERVICE_PORT_HTTPS= 443KUBERNETES_SERVICE_HOST= 10.254. 0.1MY_SERVICE_PORT_80_TCP_PORT= 80PWD=/MY_SERVICE_PORT_80_TCP_PROTO=tcp
$ systemctl restart kubelet
# 列出當前節點名kubectl get nodeNAME STATUS AGE127.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.yamlYAML error: found character that cannot start any token# orerror:yaml: line 15: found a tab character that violate indentation#file.yaml不可用tab鍵來空格$ sudo kubectl create -f mysql-rc.yamlerror: 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-namespacesNAMESPACE NAME READY STATUS RESTARTS AGEdefault my-nginx- 379829228-b796w 1/ 1 Running 0 12mkube-system kubernetes-dashboard- 2397086622- 46tvx 0/ 1 ContainerCreating 0 8s[root@node01 ~] # kubectl logs -f kubernetes-dashboard-2397086622-46tvx --namespace=kube-systemUsing HTTP port: 9090Using apiserver-host location: http:// 127.0. 0.1: 8080Creating API server client for http:// 127.0. 0.1: 8080Error 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 refusedRefer to the troubleshooting guide for more information: https://github.com/kubernetes/dashboard/blob/master/docs/user-guide/troubleshooting.md