kubernates

开始

首先说一下,下面的内容参考于

kuebernetes安装

这里使用简单的方式 (在centos7下进行安装)

首先关闭centos7的防火墙

[root@163-44-169-37 ~]# service firewalld stop
or
[root@163-44-169-37 ~]# systemctl disable firewalld
or
[root@163-44-169-37 ~]# systemctl stop firewalld

安装etcd和kubernetes软件

可以看到安装kubernetes软件包的过程中同时下载的依赖包含如下,其中有docker的安装。
这里写图片描述

修改配置文件

[root@163-44-169-37 ~]# vim /etc/sysconfig/docker
OPTIONS='--selinux-enabled=false --insecure-registry gcr.io'

[root@163-44-169-37 ~]# vim /etc/kubernetes/apiserver
default admission control policies中的
ServiceAccount参数删除

启动服务

[root@163-44-169-37 ~]# systemctl start etcd
[root@163-44-169-37 ~]# systemctl start docker
[root@163-44-169-37 ~]# systemctl start kube-apiserver
[root@163-44-169-37 ~]# systemctl start kube-controller-manager
[root@163-44-169-37 ~]# systemctl start kube-scheduler
[root@163-44-169-37 ~]# systemctl start kubelet
[root@163-44-169-37 ~]# systemctl start kube-proxy

创建我们集群服务

创建我们的RC文件

[root@163-44-169-37 ~]# vim redis-master-controller.yaml

文件内容如下
note:here,you should take care of the marker that indented is strict, you’d used a two spaces instead of a tab.

apiVersion: v1
kind: ReplicationController
metadata:
  name: redis-master
  labels:
    name: redis-master
spec:
  replicas: 1
  selector:
    name: redis-master
  template:
    metadata:
      labels:
        name: redis-master
    spec:
      containers:
      - name: master
        image: kubeguide/redis-master
        ports:
        - containerPort: 6379

这里写图片描述
vim语法标亮是遵循的yaml语法。

[root@163-44-169-37 ~]# kubectl create -f redis-master-controller.yaml

next,查看我们刚刚创建的redis-master和pods.

[root@163-44-169-37 ~]# kubectl get rc
NAME           DESIRED   CURRENT   AGE
redis-master   1         1         7m

[root@163-44-169-37 ~]# kubectl get pods
NAME                 READY     STATUS    RESTARTS   AGE
redis-master-k2vlr   1/1       Running   0          9m

运行docker的命令的话会发现

[root@163-44-169-37 ~]# docker ps
CONTAINER ID  IMAGE                     COMMAND  
de36d2823bc1  kubeguide/redis-master "redis-server /etc/re"  
89c371be051e  registry.access.redhat.com/rhel7/pod-infrastructure:latest   "/pod"  

可以看到docker启动了两个容器,一个是pods,另一个是我们的redis服务

提供redis服务的pod已经创建并正常运行了,接下来创建与之关联的service(服务)——-redis-master的定义文件(文件名为redis-master-service.yaml)
文件内容如下

apiVersion: v1
kind: Service
metadata:
  name: redis-master
  labels:
    name: redis-master
spec:
  ports:
  - port: 6379
    targetPort: 6379
  selector:
    name: redis-master

这里写图片描述

创建service

[root@163-44-169-37 ~]# kubectl create -f redis-master-service.yaml
service "redis-master" created

查看我们刚刚创建的service

[root@163-44-169-37 ~]# kubectl get services
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.254.0.1      <none>        443/TCP    2h
redis-master   10.254.33.208   <none>        6379/TCP   5m

注意我们的service被分配了一个虚拟ip10.254.33.208,之后要部署的redis-slave和php-frontend两组pods都将通过10.254.33.208:6379来访问redis-master服务。

note:我们所创建的redis-master的ip地址是随机分配的,那么如何自动化的让我们后面将要启动的两个服务能够得到redis-master的IP地址呢?
kubernetes的解决方案是通过linux的环境变量,在每一个pods的容器里增加环境变量。以此让我们的pods中的其他服务得以知道所要访问的ip.
本例中就应该是
REDIS_MASTER_SERVICE_HOST=10.254.33.208
和
REDIS_MASTER_SERVICE_PORT=6379

创建redis-slave服务

[root@163-44-169-37 ~]# vim redis-slave-controller.yaml

redis-slave-controller.yaml的内容如下

apiVersion: v1
kind: ReplicationController
metadata:
  name: redis-slave
  labels:
    name: redis-slave
spec:
  replicas: 2
  selector:
    name: redis-slave
  template:
    metadata:
      labels:
        name: redis-slave
    spec:
      containers:
      - name: slave
        image: kubeguide/guestbook-redis-slave
        env:
        - name: GET_HOST_FROM
          value: env
        ports:
        - containerPort: 6379

这里写图片描述

[root@163-44-169-37 ~]# kubectl create -f redis-slave-controller.yaml
replicationcontroller "redis-slave" created

查看RC和pods

[root@163-44-169-37 ~]# kubectl get rc
NAME           DESIRED   CURRENT   AGE
redis-master   1         1         46m
redis-slave    2         2         3m
[root@163-44-169-37 ~]# kubectl get pods
NAME                 READY     STATUS    RESTARTS   AGE
redis-master-k2vlr   1/1       Running   0          46m
redis-slave-gdue9    1/1       Running   0          3m
redis-slave-u2m18    1/1       Running   0          3m
[root@163-44-169-37 ~]# kubectl create -f redis-slave-service.yaml
service "redis-slave" created
[root@163-44-169-37 ~]# kubectl get services
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.254.0.1      <none>        443/TCP    2h
redis-master   10.254.33.208   <none>        6379/TCP   36m
redis-slave    10.254.40.178   <none>        6379/TCP   1m

为了实现redis数据库的主从同步,在redis-slave镜像的启动命令/run.sh中,输入如下:

redis-server --slaveof ${REDIS_MASTER_SERVICE_HOST} 6379

我们在观察下docker中的变化

[root@163-44-169-37 ~]# docker ps
CONTAINER ID        IMAGE       COMMAND                                                                  
97bd7dab2e22        kubeguide/guestbook-redis-slave                              "/entrypoint.sh /bin/" 
384fc655c097        kubeguide/guestbook-redis-slave                              "/entrypoint.sh /bin/"  
f3a0fccc8b9a        registry.access.redhat.com/rhel7/pod-infrastructure:latest   "/pod" 
5186c37b036e        registry.access.redhat.com/rhel7/pod-infrastructure:latest   "/pod"  
de36d2823bc1        kubeguide/redis-master                                       "redis-server /etc/re"  
89c371be051e        registry.access.redhat.com/rhel7/pod-infrastructure:latest   "/pod"  

创建php服务

[root@163-44-169-37 ~]# vim frontend-controller.yaml
[root@163-44-169-37 ~]# kubectl create -f frontend-controller.yaml
replicationcontroller "frontend" created

frontend-controller.yaml内容如下

apiVersion: v1
kind: ReplicationController
metadata:
  name: frontend
  labels:
    name: frontend
spec:
  replicas: 3
  selector:
    name: frontend
  template:
    metadata:
      labels:
        name: frontend
    spec:
      containers:
      - name: frontend
        image: kubeguide/guestbook-php-frontend
        env:
        - name: GET_HOST_FROM
          value: env
        ports:
        - containerPort: 80

这里写图片描述
查看rc和pod

[root@163-44-169-37 ~]# kubectl get rc
NAME           DESIRED   CURRENT   AGE
frontend       3         3         1m
redis-master   1         1         1h
redis-slave    2         2         26m
[root@163-44-169-37 ~]# kubectl get pods
NAME                 READY     STATUS    RESTARTS   AGE
frontend-1csm5       1/1       Running   0          2m
frontend-544p4       1/1       Running   0          2m
frontend-js5df       1/1       Running   0          2m
redis-master-k2vlr   1/1       Running   0          1h
redis-slave-gdue9    1/1       Running   0          27m
redis-slave-u2m18    1/1       Running   0          27m

最后创建service

[root@163-44-169-37 ~]# vim frontend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    name: frontend
spec:
  type: NodePort
  ports:
  - port: 80
    nodePort: 30001
  selector:
    name: frontend

这里写图片描述
note:在上述文件中service通过NodePort属性给kubernetes集群中的service映射一个外网可以访问的端口。这里的端口有限制,为(30000~32767)

[root@163-44-169-37 ~]# kubectl create -f frontend-service.yaml
You have exposed your service on an external port on all nodes in your
cluster.  If you want to expose this service to the external internet, you may
need to set up firewall rules for the service port(s) (tcp:30001) to serve traffic.

See http://releases.k8s.io/release-1.2/docs/user-guide/services-firewalls.md for more details.
service "frontend" created

提示创建完成,并且给了一个kindly notice.
查看service

[root@163-44-169-37 ~]# kubectl get services
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
frontend       10.254.43.89    nodes         80/TCP     2m
kubernetes     10.254.0.1      <none>        443/TCP    3h
redis-master   10.254.33.208   <none>        6379/TCP   57m
redis-slave    10.254.40.178   <none>        6379/TCP   22m

另外这个例子中的controller.js有一个错误的
修改过程如下(最好是在镜像中修改,否则得分别对三个service服务修改3次)

[root@163-44-169-37 ~]# docker ps
[root@163-44-169-37 ~]# docker exec -ti 容器id /bin/bash

root@frontend-1csm5:/var/www/html# apt-get -y install vim
root@frontend-1csm5:/var/www/html# vim controllers.js

修改27行的
 data.data.split(",");改为data.split(",");

root@frontend-1csm5:/var/www/html# exit

演示图如下:

这里写图片描述

kubernetes的详细理解

Node,Pod,Replication Controller,Service

Node

相对于master而言的物理机或者虚拟机,
其拥有:
1. 启动和管理pod的服务—kuberlet
2. kube-proxy
3. docker daemon
结构:
1. Node地址 主机的ip地址,或者Node ID
2. Node运行状态: (Pending,Running,Terminated)
3. Node Condition 目前只有一种Ready
4. Node系统容量:可用系统资源,包括cpu,内存数量,最大可调度Pod数量
5. 其他:内核版本号,Kubernetes版本号,Docker版本号,操作系统名称.

查看node信息

[root@163-44-169-37 ~]# kubectl describe node

node controller是kubernetes的一个组件,用于对node管理
1. 集群范围内node信息同步
2. 单个node的生命周期管理

node注册

kubelet自注册

kubenetes的推荐注册方式
kubelet自注册参数

optiondescription
- -apiserver=:apiserver的地址
- -kubeconfig=:登陆apiserver所需凭据/证书的目录
- -cloud_provider=:云服务商地址,用于获取自身的metadata
- -register-node=:设置为true表示自动注册到apiserver

kubelet手动注册

Pod

pod的出现是为了解决docker隔离容器之间必须通过link方式才能互相访问的问题。
一个pod中的应用容器共享同一组资源
- PID命名空间:可以看到其它应用程序的进程ID
- 网络命名空间:能够访问同一个ip和端口范围
- IPC命名空间:能够使用SystemV IPC或POSIX消息队列进行通信
- UTS命名空间:共享主机名
- Volumes(共享存储卷):能够访问POD级别定义的Volumes

生命周期交由replication controller管理,所含容器运行结束后,pod也结束。
pod的状态

statusdescription
pending其所包含的容器镜像还未完全创建
running其所包含的容器镜像创建完成并成功运行起来
succeeded所有容器都成功结束,并且不会被重启
failed所有容器都结束了,但是至少有一个容器是以失败状态结束的
Created with Raphaël 2.1.0 Pending Running success? Succeeded Failed yes no

Label

负责定义对象的属性

通过label selector来选择对象
包括两种选择方式
1. Equality-based
name = redis-slave
name != redis-slave
2. Set-based
name in (reids-master,redis-slave)
name not in (reids-master,redis-slave)

label与label selector共同组成了kubernetes中的最核心的应用模型,使得被管理的对象能够被精细的分组管理,同时实现了整个集群的高可用性。

Replication Controller(RC)

用于定义Pod副本的数量,在master内,controller manager进程通过RC的定义来完成Pod的创建,监控,启停等操作。
如果某个pod停止运行,就会将pod重启命令提交给node上的某个程序来完成(如kubelet或docker)

综上所述:
通过对RC的使用,kubernetes实现了应用集群的高可用性,并且大大减少了系统管理员在传统IT环境中需要完成的许多手工运维工作(如主机监控脚本,应用监控脚本,故障恢复脚本等)

如果总共有三个node,其中node1和node2上运行着redis服务,node2节点down掉,cabernets会自动创建并启动新的pod,可能在node3,也可能在node1上。

pod scaling

[root@163-44-169-37 ~]# kubectl scale rc redis-slave --replicas=3 

删除RC并不会影响通过该RC已经创建好的pod,为了删除所有的pod,可以通过设置replicas值为0,然后更新该RC.另外客户端工具kubectl提供了stop和delete命令来完成一次性删除RC和RC控制的全部pod。

Service

一个service可以看作一组提供相同服务的pod的对外访问接口。service作用于哪些pod是通过label selector来定义的

这样service与service之间访问的时候就不会关心底层到底访问的那个pod。

在pod正常启动后,系统会根据service的定义创建出与pod对应的endpoint对象,
以建立起service与后端pod的对应关系,随着pod的创建,销毁,endpoint对象也将被更新,endpoint对象主要由pod的IP地址和容器需要监听的端口号组成。通过以下指令查看endpoint对象

[root@163-44-169-37 ~]# kubectl get endpoints
NAME           ENDPOINTS                                   AGE
frontend       172.17.0.5:80,172.17.0.6:80,172.17.0.7:80   3h
kubernetes     163.44.169.37:6443                          6h
redis-master   172.17.0.2:6379                             3h
redis-slave    172.17.0.3:6379,172.17.0.4:6379             3h

pod IP地址和service的cluster ip地址不同
pod:docker deamon根据docker0网桥的IP地址段进行分配的。
service:kubernetes系统中的虚拟ip地址,由系统动态分配。
一般,service的生命周期长于pod,pod会根据实际情况而被replication controller销毁,再次创建。

service如何实现外部访问?
1. NodePort
spec.type = NodePort
spec.ports.nodePort
2. LoadBalancer
spec.type = LoadBalancer
spec.ports.nodePort
status.loadBalancer.ingress.ip(设置为云服务商提供的负载均衡器的IP地址)

Volume(存储卷)

EmptyDir

Pod分配到node时创建的,pod从node上移除,EmptyDir中的数据也会永久移除。
作用:
1. 临时空间(某些应用程序所需,无需长久保存)
2. 长时间任务的中间过程,CheckPoint临时保存目录
3. 同一个pod内,多容器共享目录

hostPath

在pod上挂载宿主机上的文件夹或目录。
作用:
1. 容器应用程序生成的日志文件需要永久保存。
2. 需要访问宿主机上的docker引擎内部数据结构的容器应用

gcePersistentDisk

使用谷歌计算引擎(Google Compute Engine,GCE)上永久磁盘上的文件。
1. node需要是GCE虚拟机
2. 这些虚拟机需要与PD存在于相同的GCE项目和Zone中。

通过gcloud命令即可创建一个PD
gcloud compute disks create --size=500GB --zone=us-centrall-a my-data-disk

awsElasticBlockStore

和上面的gce类似,需要使用Amazon提供的Amazon Web Services(AWS)的EBS Volume。
通过aws ec2 create-volume命令创建一个EBS volume

was ec2 create-volume --availability-zone eu-west-la --size 10 --volume-type gp2 

nfs

iscsi

使用iSCSI存储设备上的目录挂载到Pod中。

glusterfs

使用开源的GlusterFS网络文件系统的目录挂载到Pod中。

rbd

使用linux块设备共享存储(Rados Block Device)挂载到Pod中

gitRepo

通过挂载一个空目录,并从git库中clone一个git repository以供Pod使用

secret

tmfs(内存文件系统实现)

persistentVolumeClaim

通常是一种网络存储,例如GCEPersistentDisk.AWSElasticBlockStore,NFS,iSCSI等。

Namespace

[root@163-44-169-37 ~]# kubectl get namespaces
NAME      STATUS    AGE
default   Active    7h

创建新的namespace

[root@163-44-169-37 ~]# vim namespace-dev.yaml
[root@163-44-169-37 ~]# kubectl create -f namespace-dev.yaml
namespace "development" created

namespace-dev.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: development

在创建pod的时候可以指定pod属于哪个namespace。
这样的话使用# kubectl get pods讲无法显示。
命令需要改为# kubectl get pods –namespace=development

可以通过namespace来实现用户分组,即”多租户”管理。对不同的租户还可以进行单独的资源配额设置和管理。

Annotation(注解)

与label类似
用户任意定义的附加信息。
以便于外部工具进行查找。
记录的信息如下:
1. build信息、release信息、docker镜像信息
2. 日志库、监控库、分析库等资源库的地址信息
3. 程序调试工具信息,例如工具名称,版本号
4. 团队的联系信息,例如电话号码、负责人名称、网址等

kubernetes final

下面是一个大致的流程图
这里写图片描述
kubernetes的工作是由
1. API Server:提供资源对象的唯一操作入口,全量查询+变化监听
2. Controller Manager:集群内部的管理控制中心,故障检测和恢复的自动化工作。
3. Scheduler:集群的调度器,负责Pod在集群节点中的调度分配
4. Kubelet:负责本节点上的Pod的创建、修改、监控、删除等全生命周期的管理。同时定时上报本Node的信息到API Server里
5. Proxy:实现了service的代理以及软件模式的负载均衡器
6. kubectl:客户端工具,访问kubernetes系统

Node节点运行的Kubelet服务中内嵌了一个cAdvisor服务,用于实时监控Docker上运行的容器的性能指标。
cAdvisor是google的另一个开源项目。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值