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
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
修改两处配置
- Docker配置文件/etc/sysconfig/docker, OPTIONS=’–selinux-enabled=false –insecure-registry gcr.io’
- 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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
初入门小实例
部署nginx服务
$ kubectl run my-nginx --image=nginx --port=80 $ kubectl get pod # 查看pod
- 1
- 2
发现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
- 1
- 2
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
- 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
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
对比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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
重要名词
名词 翻译 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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
启动管理服务
# 根据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.
- 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
- 29
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
宿主主机内访问该服务
同网段的机器访问该服务
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 # 作用效果等同上一条命令
- 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
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
# vi env-config.yaml apiVersion: v1 kind: ConfigMap metadata: name: env-config namespace: default data: log_level: INFO
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
可以在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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
启动等一系列操作
$ 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
- 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
- 29
- 30
- 31
- 32
- 33
- 34
$ 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
- 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
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
ConfigMap的限制条件
- ConfigMap必须在Pod之前创建才能被使用。
- ConfigMap可以定义其属于哪个Namspece,只有在同一个Namespace中的pod才能引用。
删除Pod
- 有时候deployment、rs、rc、services都为0,但是Pod确存在着。则重启kubelet服务即可。
$ systemctl restart kubelet
- 1
补充
# 列出当前节点名 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}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
我们最好不要越过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键来空格
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e44c3c0e64.css" rel="stylesheet"> </div>