k8s中文文档

  • k8s概念比较多,有什么概念的疑惑的推荐看k8s中文文档。

me的环境

  • 操作系统:centos7
  • docker:1.12.6

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

还慌?那就直接用网页在线版的kubernets

kubernets单机版安装部署

kubernetes部署算是有一定门槛的。为了不从入门到放弃,推荐一开始安装单机版作为入门熟悉kubectl指令、了解工作原理。

  • 安装流程,切换成root

    
    
    # 关闭centos自带的防火墙
    $ sudo systemctl disable firewalld
    $ sudo systemctl stop firewalld
    # 安装etcd和kubernetes软件(会自动安装docker)
    $ sudo 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}

报错


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

kubernetes入门实践的更多相关文章

  1. 微服务 + Docker + Kubernetes 入门实践 目录

    微服务 + Docker + Kubernetes 入门实践: 微服务概念 微服务的一些基本概念 环境准备 Ubuntu & Docker 本文主要讲解在 Ubuntu 上安装和配置 Dock ...

  2. 分布式学习系列【dubbo入门实践】

    分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...

  3. sass、less和stylus的安装使用和入门实践

    刚 开始的时候,说实话,我很反感使用css预处理器这种新玩意的,因为其中涉及到了编程的东西,私以为很复杂,而且考虑到项目不是一天能够完成的,也很少是 一个人完成的,对于这种团队的项目开发,前端实践用c ...

  4. Django入门实践(三)

    Django入门实践(三) Django简单应用 前面简单示例说明了views和Template的工作过程,但是Django最核心的是App,涉及到App则会和Model(数据库)打交道.下面举的例子 ...

  5. Django入门实践(二)

    Django入门实践(二) Django模板简单实例 上篇中将html写在了views中,这种混合方式(指Template和views混在一起)不适合大型开发,而且代码不易管理和维护,下面就用Djan ...

  6. Django入门实践(一)

    Django入门实践(一) Django编程思路+入门 认识Django有一个多月了,我觉得学习Django应该先理清它的编程思路.它是典型的MVC框架(在Django里也称MTV),我觉得Djang ...

  7. 全文搜索引擎Elasticsearch入门实践

    全文搜索引擎Elasticsearch入门实践 感谢阮一峰的网络日志全文搜索引擎 Elasticsearch 入门教程 安装 首先需要依赖Java环境.Elasticsearch官网https://w ...

  8. 【实战】Docker入门实践二:Docker服务基本操作 和 测试Hello World

    操作环境 操作系统:CentOS7.2 内存:1GB CPU:2核 Docker服务常用命令 docker服务操作命令如下 service docker start #启动服务 service doc ...

  9. Cookie快速入门实践

    第一个servlet[比如是CookieDemo01]中的代码如下: import javax.servlet.http.Cookie; //--------省略若干代码----------- pro ...

随机推荐

  1. Lua如何管理”package”

    Lua如何管理"package" 方式一: 私有方法和变量都需要显式定义为local类型的,这很容易造成错误.一旦不小心漏写,就又将方法定义为全局的了. "package ...

  2. CodeForces - 853A Planning (优先队列,贪心)

    Helen works in Metropolis airport. She is responsible for creating a departure schedule. There are n ...

  3. C. New Year and Rating

    C. New Year and Rating time limit per test 2 seconds memory limit per test 256 megabytes input stand ...

  4. web前端免费资源集

    web前端免费资源集 https://github.com/vhf/free-programming-books/blob/master/free-programming-books-zh.md

  5. yum常用选项和参数

    列举包文件 # yum list #列出资源库中所有可以安装或更新的rpm包 # yum list updates #列出资源库中所有可以更新的rpm包 # yum list installed #列 ...

  6. linux-mv

    linux-mv 主要用于文件或者目录的移动或者改动, 命令参数 -i:ruguo目标文件或者目录存在,提示是否覆盖目标文件或目录 -f:无论目标文件是否存在,直接覆盖,不提示, 有好多参数,自己可以 ...

  7. 【WEB API项目实战干货系列】- API访问客户端(WebApiClient适用于MVC/WebForms/WinForm)(四)

    这几天没更新主要是因为没有一款合适的后端框架来支持我们的Web API项目Demo, 所以耽误了几天, 目前最新的代码已经通过Sqlite + NHibernate + Autofac满足了我们基本的 ...

  8. 使用js获取数组中最大、最小的数字

    1.查询最大值 var maxValue=Math.max.apply(Math,array); 2.查询最小值 var minValue=Math.min.apply(Math,array);

  9. RE:通过移动端滑动手势实现数据加载

      背景:         基于要尝试的移动端项目需要有一个通过上拉下滑手势达成加载不同数据的功能,其涉及到滑动手势和ajax数据加载方面的知识点.故对整个实现过程做一个记录整理.个人JS功底有限,看 ...

  10. Asp.Net Core API网关Ocelot

    首先,让我们简单了解下什么是API网关? API网关是一个服务器,是系统的唯一入口.从面向对象设计的角度看,它与外观模式类似.API网关封装了系统内部架构,为每个客户端提供一个定制的API.它可能还具 ...