Kubernetes(K8s)

               Kubernetes

1.基础介绍总结

service是分布式集群系统的核心,底下的每一项server都有四种特性

1.拥有一个唯一指定的名字比如(name=mysql-server)

2.拥有唯一的虚拟ip(Cluster,ip,service ip或vip)和端口号

3.能够提供某种远程服务能力

4.被映射到了提供服务能力的一组容器应用上

1.service的服务进程目前都基于soker通讯方式对外提供服务比如(redis,mysql,memcache,web)实现了某个具体业务的一个特定TCP server进程

2.service通常由多个相关服务进程提供服务,每个进程都有一个独立的Endpoint(IP+Port)访问点。但Kubernetes 能够让我们通过Service虚拟Cluster IP+Service Port连接到指定的Service上

3. Kubernetes有内建的透明负载均衡和故障恢复机制,不管后端有多少服务进程,也不管某个服务进程是否会由于发生故障而重新部署到其他机器,都不会影响到我们对服务的正常调用

4. 更重要的是这个Service本身一旦创建就不再变化,这意味着Kubernetes集群中,我们再也不用为了服务的IP地址变来变去的问题而头疼。

Kubrnetes Pod介绍

Pod概念 Pod运行在一个我们称之为节点Node的环境中,可以是私有云也可以是公有云的虚拟机或者物理机,通常在一个节点上运行几百个Pod;其次,每个Pod里运行着一个特殊的被称之为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此他们之间的通讯和数据交换更为高效。在设计时我们可以充分利用这一特征将一组密切相关的服务进程放入同一个Pod中。

并不是每个Pod和它里面运行的容器都能映射到一个Service 上,只有那些提供服务(无论是对内还是对外)的一组Pod才会被映射成一个服务。

service和Pod如何关联

容器提供了强大的隔离功能,所以有必要把为Service提供服务的这组进程放入到容器中隔离。Kubernetes设计了Pod对象,将每个服务进程包装到相应的Pod中,使其成为Pod中运行的一个容器Container。为了建立Service 和Pod间的关联关系,Kubernetes 首先给每个Pod填上了一个标签Label,给运行MySQL的Pod贴上name=mysql标签,给运行PHP的Pod贴上name=php标签,然后给相应的Service定义标签选择器Label Selector,比如MySQL Service的标签选择器的选择条件为name=mysql,意为该Service 要作用于所有包含name=mysql Label的Pod上。这样就巧妙的解决了ServicePod关联问题


Kubernetes RC介绍

RC介绍 在Kubernetes集群中,你只需要为需要扩容的Service关联的Pod创建一个RC Replication Controller则该Service的扩容以至于后来的Service升级等头疼问题都可以迎刃而解。 定义一个RC文件包括以下3个关键点

  • (1) 目标Pod的定义
  • (2) 目标Pod需要运行的副本数量(Replicas)
  • (3) 要监控的目标Pod的标签(Label)

在创建好RC系统自动创建好Pod后,kubernetes会通过RC中定义的Label筛选出对应的Pod实例并实时监控其状态和数量,如果实例数量少于定义的副本数量Replicas,则会用RC中定义的Pod模板来创建一个新的Pod,然后将此Pod调度到合适的Node上运行,直到Pod实例的数量达到预定目标。这个过程完全是自动化的,无需人干预。只要修改RC中的副本数量即可。

Kubernetes Master介绍

Master介绍 Kubernetes 里的Master指的是集群控制节点,每个Kubernetes集群里需要有一个Master节点来负责整个集群的管理和控制,基本上Kubernetes所有的控制命令都发给它,它负责具体的执行过程,我们后面执行的所有命令基本上都是在Master节点上运行的。如果Master宕机或不可用,那么集群内容器的管理都将失效

Master节点上运行着以下一组关键进程:

  • [ ] Kubernetes API Server (kube-apiserver):提供了HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程
  • [ ] Kubernetes Controller Manager (kube-controller-manager):Kubernetes里所有的资源对象的自动化控制中心
  • [ ] Kubernetes Scheduler (kube-scheduler):负责资源调度(Pod调度)的进程

另外在Master节点上还需要启动一个etcd服务,因为Kubernetes里的所有资源对象的数据全部是保存在etcd

 

Kubernetes Node介绍

Node介绍 除了Master,集群中其他机器被称为Node节点,每个Node都会被Master分配一些工作负载Docker容器,当某个Node宕机时,其上的工作负载会被Master自动转移到其他节点上去。

每个Node节点上都运行着以下一组关键进程。

  • [x] kubelet负责Pod对应容器的创建、停止等任务,同时与Master节点密切协作,实现集群管理的基本功能
  • [x] kube-proxy实现Kubernetes Service的通信与负载均衡机制的重要组件。
  • [x] Docker Engine(Docker)Docker引擎,负责本机的容器创建和管理工作。

Kubernetes 中Master与Node工作内容

在集群管理方面,Kubernets将集群中的机器划分为一个Master节点和一群工作节点(Node),其中,在Master节点上运行着集群管理相关的一组进程kube-apiserver、kube-controller-manager和kube-scheduler,这些进程实现了整个集群的资源管理、Pod调度、弹性收缩、安全控制、系统监控和纠错等管理功能,并且都是全自动完成的。Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的kubelet、kube-proxy服务进程,这些服务进程负责Pod创建、启动、监控、重启、销毁、以及实现软件模式的负载均衡 

2. Kubernetes Pod

Pod 介绍

每个Pod都有一个特殊的被称为根容器Pause容器。Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器 

为什么Kubernetes会设计出一个全新的Pod概念,并且有这样特殊的结构?

原因一:Pause容器作为Pod根容器,以它的状态代表整个容器组的状态 原因二: Pod里的多个业务容器共享Pause容器的IP,共享Pause容器挂接的Volume

Kubernetes为每个Pod分配唯一IP的地址,称之为Pod IP,一个Pod里的多个容器共享Pod IP。Kubernetes要求底层网络支持集群内任意两个Pod之间的TCP/IP的直接通讯,采用虚拟二层网络技术来实现,一个Pod里的容器与另外主机上的Pod容器能够直接通信。

静态Pod&普通Pod

普通的Pod:

普通Pod:一旦被创建,就会被放入到etcd中存储,随后会被Kubernetes Master调度到某个具体的Node上并进行绑定(Binding),随后该Pod 被对应的Node上的kubelet进程实例化成一组相关的docker容器运行起来。     当Pod里的某个容器停止时,Kubernetes会自动检测到这个问题并且重新启动这个Pod (重启Pod里的所有容器),如果Pod所在的Node宕机,则会将这个Node上所有的Pod从新调度到其他节点上。

静态Pod (STatic Pod)
静态Pod不存放在Kubernetes的etcd存储里,而是存放在某个具体的Node上的文件中,并且只在此Node上启动运行。

静态Pod是由kubelet进行管理的仅存在于特定Node上的Pod。他们不能通过API Server进行管理,无法与ReplicationController(RC)、Deployment、或者DaemonSet进行关联,并且kubelet也无法对它们进行健康检查。静态Pod总是由kubelet进行创建的,并且总是在kubelet所在的Node上运行的

创建静态Pod有两种方式:配置文件方式和HTTP方式

1.配置文件方式

首先,需要设置kubelet的启动参数"config",指定kubelet需要监控的配置文件所在的目录,kubelet会定期扫描该目录,并根据该目录中的*.yaml*.json文件进行创建操作

部署静态Pod

1.选择一个节点来运行静态pod

[root@abcdocker ~] $ ssh master

2.选择一个目录,例如/etc/kubelet.d,把web服务器的pod定义文件放在这个目录下,例如/etc/kubelet.d/static-web.yaml:

[root@my-node1 ~] $ mkdir /etc/kubelet.d/
[root@my-node1 ~] $ cat <<EOF >/etc/kubelet.d/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
EOF

3.配置节点上的kubelet使用这个目录,kubelet启动时增加--pod-manifest-path=/etc/kubelet.d/参数。如果是Fedora系统,在Kubelet配置文件/etc/kubernetes/kubelet中添加下面这行:

...
KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/"
...

4.重启kubelet

[root@abcdocker ~]  systemctl restart kubelet

提示:由于Pod无法通过API Server直接进行管理,所以Master节点尝试删除这个Pod,将会使其状态变成Pending状态,且不会被删除

Endpoint

Pod的IP加上这里的容器端口(container Port),就组成了一个全新的概念---Endpoint 它代表着此Pod里的一个服务进程的对外通讯地址。一个Pod也存在着多个Endpoint的情况,比如我们把Tomcat定义为一个Pod时,可以对外暴露端口与服务端口这两个Endpoint

Event

Event是一个事件记录,记录事件的最早生成时间、最后重现时间、重复次数、发起者、类型,以及导致此事件的原因等众多信息。Event通常会关联到某个具体的资源上,是排查故障的重要参考,Node描述信息包含了Event,而Pod同样有Event记录。

当我们发现某个Pod迟迟无法创建时,我们就可以用kubectl describe pod [Pod名称]来查看,定位问题

演示:

$ 使用kubectl get pod 可以查到当前Pod数

[root@master ~]# kubectl get pod

NAME                                READY     STATUS              RESTARTS   AGE

nginx-deployment-5c6b9976cc-2qbkr   0/1       ContainerCreating   0          14s

nginx-deployment-5c6b9976cc-bqtvp   0/1       ContainerCreating   0          14s

nginx-deployment-5c6b9976cc-ttdrz   0/1       ContainerCreating   0          14s

 

$ 使用kubetctl describe pod [Pod名称]可以看到Pod详细信息

[root@master ~]# kubectl describe pod nginx-deployment-5c6b9976cc-2qbkr

 

Events:

  Type     Reason                  Age               From               Message

  ----     ------                  ----              ----               -------

  Normal   Scheduled               35s               default-scheduler  Successfully assigned default/nginx-deployment-5c6b9976cc-2qbkr to master

  Warning  FailedCreatePodSandBox  6s (x2 over 28s)  kubelet, master    Failed create pod sandbox: rpc error: code = Unknown desc = failed pulling image "gcr.io/google_containers/pause-amd64:3.0": Error response from daemon: Get https://gcr.io/v1/_ping: dial tcp 74.125.203.82:443: getsockopt: connection timed out

一个完整的Pod,正常创建没有错误如下

$ 显示一个Pod完整信息

[root@master ~]# kubectl describe pod tomcat-6755d5587c-nfjst

Name:           tomcat-6755d5587c-nfjst

Namespace:      default

Node:           master/192.168.60.24

Start Time:     Wed, 18 Jul 2018 16:29:37 +0800

Labels:         app=abcdocker

                pod-template-hash=2311811437

Annotations:    <none>

Status:         Running

IP:             172.17.0.2

Controlled By:  ReplicaSet/tomcat-6755d5587c

Containers:

  tomcat:

    Container ID:   docker://415acd35b6d4ed3effd26e2d9a958a56e83619243b0216690e0573a6c079bf1f

    Image:          daocloud.io/library/tomcat

    Image ID:       docker-pullable://daocloud.io/library/tomcat@sha256:1c39cc2e882b4169199888

    Port:           80/TCP

    Host Port:      0/TCP

    State:          Running

      Started:      Wed, 18 Jul 2018 16:33:18 +0800

    Ready:          True

    Restart Count:  0

    Environment:    <none>

    Mounts:

      /var/run/secrets/kubernetes.io/serviceaccount from default-token-cbkfr (ro)

Conditions:

  Type              Status

  Initialized       True

  Ready             True

  ContainersReady   True

  PodScheduled      True

Volumes:

  default-token-cbkfr:

    Type:        Secret (a volume populated by a Secret)

    SecretName:  default-token-cbkfr

    Optional:    false

QoS Class:       BestEffort

Node-Selectors:  <none>

Tolerations:     <none>

Events:          <none>

 

Pod基本用法

Pod的基本用法为:Pod 可以创建一个或多个容器组合而成

创建一个名为nginx-deploymentPod只由一个容器组成
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx   ##容器名称
        image: daocloud.io/library/nginx:1.13.0-alpine  #镜像地址
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

另一种场景,当nginx容器和tomcat容器应用为紧耦合的关系,应该组合成一个整体对外提供服务时,应将这两个容器打包为一个Pod 

配置nginx和tomcat yaml文件如下下

[root@master test]# cat abcdocker.yaml

apiVersion: apps/v1beta2

kind: Deployment

metadata:

  name: abcdocker-pod

spec:

  replicas: 1

  selector:

    matchLabels:

      app: test

  template:

    metadata:

      labels:

        app: test

    spec:

      containers:

      - name: abcdocker-nginx-docker

        image: daocloud.io/library/nginx:1.13.0-alpine

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 80

      - name: abcdocker-tomcat-docker

        image: daocloud.io/library/tomcat:8.5.21-jre8-alpine

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 8080

 

[root@master test]# kubectl create -f abcdocker.yaml

 

##参数解释

查看Pod运行状态

 

我们可以看到READY信息为2/2,表示Pod中的两个容器都成功运行了 (状态Running)

我们可以在master上查看docker上的容器 

 

查看Pod的详细信息,我们可以看到两个容器的定义及创建的过程 Event信息事件

[root@master ~]# kubectl describe pod abcdocker-pod-dc6b86f8d-7tjwp
Name:           abcdocker-pod-dc6b86f8d-7tjwp
Namespace:      default
Node:           master/192.168.60.24
Start Time:     Fri, 31 Aug 2018 11:06:02 +0800
Labels:         app=test
                pod-template-hash=872642948
Annotations:    <none>
Status:         Running
IP:             172.16.219.106
Controlled By:  ReplicaSet/abcdocker-pod-dc6b86f8d
Containers:
  abcdocker-nginx-docker:  ## 容器名称
    Container ID:   docker://63d038a53c613e0dfdb62df957035f0ab54cc5428461c33f9cbcee0118815619
    Image:          daocloud.io/library/nginx:1.13.0-alpine   ##容器镜像
    Image ID:       docker-pullable://daocloud.io/library/nginx@sha256:5c36f962c506c379bd63884976489c9c5e700c1496a6e8ea13dc404b1d258f76
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 31 Aug 2018 11:06:17 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-c6m5g (ro)
  abcdocker-tomcat-docker:  
    Container ID:   docker://42e0e6ee79860c5dac6a9103c549bd47422e8044f2c57046f6ad4dcca346f743
    Image:          daocloud.io/library/tomcat:8.5.21-jre8-alpine
    Image ID:       docker-pullable://daocloud.io/library/tomcat@sha256:96a11198cf980995e61d906ba65b1c86934ffc4c7e9381157d2aebd8981a4480
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 31 Aug 2018 11:07:20 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-c6m5g (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-c6m5g:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-c6m5g
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     <none>
Events:          <none>

Pod的配置管理 ConfigMap

应用部署的一个最佳实践是讲应用所需的配置信息与程序进行分离,这样可以使得应用程序被更好地复用,通过不同的配置也能实现灵活的功能。将应用打包为容器镜像后,可以通过环境变量或者外挂文件的方式在创建容器时进行配置注入,但在大规模容器集群中,对多个容器进行不同的配置将变得非常复杂。从kubernetes1.2开始提供了一套同意的应用配置管理方案----ConfigMap(资源对象)

ConfigMap概述

ConfigMap供容器使用的典型用法如下

  • 生成为容器内的环境变量
  • 设置容器的启动命令的启动参数 (需要设置为环境变量)
  • 以Volume的形式挂载为容器内部的文件或目录

ConfigMap以一个或多个key:value的形式保存在Kubernetes系统中供应用使用,既可以用于表示一个变量的值(例如apploglevel=info),也可以用于表示一个完整配置文件的内容(server.xml=<?xml..>..)

可以通过yaml配置文件或者直接使用kubectl create configmap来创建ConfigMap

创建ConfigMap

创建ConfigMap的方式有4种:

  • 通过直接在命令行中指定configmap参数创建,即--from-literal
  • 通过指定文件创建,即将一个配置文件创建为一个ConfigMap--from-file=<文件>
  • 通过指定目录创建,即将一个目录下的所有配置文件创建为一个ConfigMap,--from-file=<目录>
  • 事先写好标准的configmap的yaml文件,然后kubectl create -f 创建

1、使用yaml文件创建ConfigMap

==演示: 通过定义yaml配置文件方式创建ConfigMap==

cat > configmap-test.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-configmap
data:
  key1: abcdocker1
  keydir: /var/data
EOF
 
# name: configmap名称
data.key1: key1 对应的值
data.keydir: keydir对应的挂载目录
 
 
创建并查看Configmap
[root@master configmap]# kubectl create -f configmap-test.yaml
configmap/test-configmap created
[root@master configmap]# kubectl get configmaps
NAME             DATA      AGE
test-configmap   2         5s
# 这里我们可以看到创建了2data的数据,就是我们上面定义的
 
 
查看创建好的configMap
[root@master configmap]# kubectl describe configmaps test-configmap
Name:         test-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>
 
Data
====
key1:
----
abcdocker1
keydir:
----
/var/data
Events:  <none>
 
# Data下面是对应的我们上面定义的key和挂载的目录

2、使用--from-file参数创建ConfigMap

==演示: 通过--from-file参数从文件中进行创建,可以指定key的名称,也可以在一个命令行中创建多个key的ConfigMap==

语法格式
 
kubectl create configmap Name --from-file=[key=]source --from-file=[key=]source

例:当前目录下含有配置文件server.xml,可以创建一个包含该文件内容的ConfigMap

kubectl create configmap test-server.xml --from-file=server.xml

例:当前configfiles下有2个配置文件,创建一个configmap包含2个文件内容

kubectl create configmap two-conf --from-file=configfiles

3、使用--from-literal创建ConfigMap

==使用--from-literal参数进行创建的示例如下:==

kubectl create configmap test-configmap --from-literal=loglevel=info --from-literal=appdatadir=/var/data
 
[root@master ~]# kubectl describe test-configmap
Name:         test-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>
 
Data
====
appdatadir:     9 bytes
loglevel:       4 bytes
 
Events:  <none>

容器应用对ConfigMap的使用有以下两种方法

  1. 通过环境变量获取ConfigMap中的内容
  2. 通过Volume挂载的方式将ConfigMap中的内容挂载为容器内部的文件或目录

Pod中使用ConfigMap

(1) 通过环境变量方式使用ConfigMap

首先我们需要创建ConfigMap

1.创建ConfigMap
[root@master configmap]# cat configmap-test-1.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: abcdocker-configmap
data:
  keyinfo: www.abcdocker.com
  abcdockerDir: /var/data
 
kubectl create -f configmap-test-1.yaml
 
 
2.创建pod进行引用
[root@master configmap]# cat configmap-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: abcdocker-pod
spec:
  containers:
    - name: configmap-pod
      image: busybox
      command: [ "/bin/sh", "-c", "env | grep config" ]
      env:
        - name: configmapPod
          valueFrom:
            configMapKeyRef:
              name: abcdocker-configmap
              key: keyinfo
        - name: configmapDir
          valueFrom:
            configMapKeyRef:
              name: abcdocker-configmap
              key: abcdockerDir
  restartPolicy: Never
 
==================相关参数解释===================
      env:
        - name: configmapPod    ##定义环境变量名称
          valueFrom:            #key "keyinfo对应的值"
         configMapKeyRef:                     name: abcdocker-configmap     ##环境变量的值取自哪(上面创建的configmap名称)
              key: keyinfo      #configmap里对应的key
        - name: configmapDir
          valueFrom:
            configMapKeyRef:
              name: abcdocker-configmap
              key: abcdockerDir
==================================================
 
kubectl create -f configmap-pod.yaml

查看我们创建好的configmap

验证

使用命令查看所有Pod
[root@master configmap]# kubectl get pod --show-all
Flag --show-all has been deprecated, will be removed in an upcoming release
NAME                             READY     STATUS      RESTARTS   AGE
abcdocker-pod                    0/1       Completed   0          3m

查看Pod日志

从kubernetes1.6开始,引用了一个新的字段envFrom实现Pod环境内将ConfigMap中所有定义的key=value自动生成为环境变量

[root@master configmap]# cat configmap-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: abcdocker-pod
spec:
  containers:
    - name: configmap-pod
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: abcdocker-configmap  ##根据configmap中自动生成key=value环境变量
  restartPolicy: Never

通过这个定义,在容器内部将会自动生成如下环境配置需要说明的是,环境变量的名称手POSIX命名规范([a-zA-Z][a-zA-Z0-9])约束,不能以数字开头。如果包含非法字符,则系统将跳过该条环境变量的创建,并记录一个Event来描述环境变量无法生成,但不阻止Pod的启动

(2) 通过volumeMount使用ConfigMap

在本例子中包含了1个配置文件的定义 server.xml

1.创建ConfigMap
 
[root@master configmap]# cat configmap-tomcat-server.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: tomcat-server-config
data:
  server.xml: |
    <?xml version='1.0' encoding='utf-8'?>
      <Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <!--APR library loader. Documentation at /docs/apr.html -->
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
      <Listener className="org.apache.catalina.core.JasperListener" />
      <!-- Prevent memory leaks due to use of particular java/javax APIs-->
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
      <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
      <Service name="Catalina">
        <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="500" minSpareThreads="50" prestartminSpareThreads="true" />
        <Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
                   connectionTimeout="20000"
                   redirectPort="8443"
                   enableLookups="false"
                   maxPostSize="10485760"
                   URIEncoding="UTF-8"
                   disableUploadTimeout="true"
                   maxConnections="10000"
                   SSLEnabled="false"/>
        <Engine name="Catalina" defaultHost="localhost">
          <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>
          <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true">
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log." suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
          </Host>
          <Context path="" docBase="/tomcat/webapps" debug="0" reloadable="true" crossContext="true"/>
        </Engine>
       </Service>
     </Server>
 
 

查看

[root@master configmap]# kubectl get configmaps tomcat-server-config
NAME                   DATA      AGE
tomcat-server-config   1         13s
 

查看详细信息

[root@master configmap]# kubectl describe configmaps tomcat-server-config
Name:         tomcat-server-config
Namespace:    default
Labels:       <none>
Annotations:  <none>
 
Data
====
server.xml:
----
<?xml version='1.0' encoding='utf-8'?>
  <Server port="8005" shutdown="SHUTDOWN">
  <Listener 
.....
 
 
 

2. 引用ConfigMap

Pod中的定义,将文件以mount挂载到容器内部定义的目录中去。Pod配置文件如下
 
 
[root@master configmap]# cat test.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - image: busybox
        imagePullPolicy: IfNotPresent
        name: tomcatpod
        volumeMounts:
        - mountPath: /tmp/server.xml
          name: serverxml
          subPath: server.xml
        ports:
        - containerPort: 8080
        command: ["tail", "-f", "/dev/null"]
      volumes:
      - name: serverxml
        configMap:
          name: tomcat-server-config
          items:
          - key: server.xml
            path: server.xml
 
kubectl create -f test.yaml        
===================参数解释===============
        volumeMounts:
        - mountPath: /tmp/server.xml  ##挂在到容器内的目录
          name: serverxml     #挂载名称(需要和volume的名称对应上)
          subPath: server.xml   #不加subPath会替换整个目录
        ports:
        - containerPort: 8080
        command: ["tail", "-f", "/dev/null"]
      volumes:
      - name: serverxml         #volumemount名称
        configMap:
          name: tomcat-server-config   #创建的configmap名称
          items:
          - key: server.xml     #对应的key
            path: server.xml    #挂载到目录的key名称
####################################
 
需要注意的是,不可以光mount挂载,需要执行命令让容器在前台运行!

验证 登陆容器可以在tmp目录下看到我们的server.xml

如果在引用ConfigMap时不指定items,则使用volumeMount方式在容器内的目录中为每个item生成一个文件夹为key的文件

[root@master configmap]# cat test_vo.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - image: busybox
        imagePullPolicy: IfNotPresent
        name: tomcatpod
        volumeMounts:
        - mountPath: /tmp/server.xml
          name: serverxml
          subPath: server.xml
        ports:
        - containerPort: 8080
        command: ["tail", "-f", "/dev/null"]
      volumes:
      - name: serverxml
        configMap:
          name: tomcat-server-config

验证

ConfigMap小结 使用ConfigMap的限制条件如下

  • ConfigMap必须在Pod之前创建
  • ConfigMap受Namespace限制,只有处于相同Namespace中的Pod可以引用它
  • ConfigMap中的配额管理还未能实现
  • Kubelet只可以支持可以被API Server管理的Pod使用ConfigMap。kubelet在本Node上通过 --manifest-url或--config自动创建的静态Pod将无法引用ConfigMap
  • 在Pod对ConfigMap进行挂载volumeMount操作时,容器内部只能挂载"目录",无法挂载为文件。在挂载到容器内部后,目录中将包含ConfigMap定义的每个item,如果该目录下原来还有其他文件,则容器内的该目录将会被挂载的ConfigMap覆盖。如果应用程序需要保留原来的其他文件,则需要进行额外的处理。可以将ConfigMap挂载到容器内部的临时目录,再通过启动脚本将配置文件复制或者链接到(cp link)应用所用的实际配置目录下
  • 需要注意的是,容器不可以光mount挂载,需要执行命令让容器在前台运行!
  • 需要在挂载下面添加subPath,否则将会替换整个目录

 

               Kubernetes

1.基础介绍总结

service是分布式集群系统的核心,底下的每一项server都有四种特性

1.拥有一个唯一指定的名字比如(name=mysql-server)

2.拥有唯一的虚拟ip(Cluster,ip,service ip或vip)和端口号

3.能够提供某种远程服务能力

4.被映射到了提供服务能力的一组容器应用上

1.service的服务进程目前都基于soker通讯方式对外提供服务比如(redis,mysql,memcache,web)实现了某个具体业务的一个特定TCP server进程

2.service通常由多个相关服务进程提供服务,每个进程都有一个独立的Endpoint(IP+Port)访问点。但Kubernetes 能够让我们通过Service虚拟Cluster IP+Service Port连接到指定的Service上

3. Kubernetes有内建的透明负载均衡和故障恢复机制,不管后端有多少服务进程,也不管某个服务进程是否会由于发生故障而重新部署到其他机器,都不会影响到我们对服务的正常调用

4. 更重要的是这个Service本身一旦创建就不再变化,这意味着Kubernetes集群中,我们再也不用为了服务的IP地址变来变去的问题而头疼。

Kubrnetes Pod介绍

Pod概念 Pod运行在一个我们称之为节点Node的环境中,可以是私有云也可以是公有云的虚拟机或者物理机,通常在一个节点上运行几百个Pod;其次,每个Pod里运行着一个特殊的被称之为Pause的容器,其他容器则为业务容器,这些业务容器共享Pause容器的网络栈和Volume挂载卷,因此他们之间的通讯和数据交换更为高效。在设计时我们可以充分利用这一特征将一组密切相关的服务进程放入同一个Pod中。

并不是每个Pod和它里面运行的容器都能映射到一个Service 上,只有那些提供服务(无论是对内还是对外)的一组Pod才会被映射成一个服务。

service和Pod如何关联

容器提供了强大的隔离功能,所以有必要把为Service提供服务的这组进程放入到容器中隔离。Kubernetes设计了Pod对象,将每个服务进程包装到相应的Pod中,使其成为Pod中运行的一个容器Container。为了建立Service 和Pod间的关联关系,Kubernetes 首先给每个Pod填上了一个标签Label,给运行MySQL的Pod贴上name=mysql标签,给运行PHP的Pod贴上name=php标签,然后给相应的Service定义标签选择器Label Selector,比如MySQL Service的标签选择器的选择条件为name=mysql,意为该Service 要作用于所有包含name=mysql Label的Pod上。这样就巧妙的解决了ServicePod关联问题


Kubernetes RC介绍

RC介绍 在Kubernetes集群中,你只需要为需要扩容的Service关联的Pod创建一个RC Replication Controller则该Service的扩容以至于后来的Service升级等头疼问题都可以迎刃而解。 定义一个RC文件包括以下3个关键点

  • (1) 目标Pod的定义
  • (2) 目标Pod需要运行的副本数量(Replicas)
  • (3) 要监控的目标Pod的标签(Label)

在创建好RC系统自动创建好Pod后,kubernetes会通过RC中定义的Label筛选出对应的Pod实例并实时监控其状态和数量,如果实例数量少于定义的副本数量Replicas,则会用RC中定义的Pod模板来创建一个新的Pod,然后将此Pod调度到合适的Node上运行,直到Pod实例的数量达到预定目标。这个过程完全是自动化的,无需人干预。只要修改RC中的副本数量即可。

Kubernetes Master介绍

Master介绍 Kubernetes 里的Master指的是集群控制节点,每个Kubernetes集群里需要有一个Master节点来负责整个集群的管理和控制,基本上Kubernetes所有的控制命令都发给它,它负责具体的执行过程,我们后面执行的所有命令基本上都是在Master节点上运行的。如果Master宕机或不可用,那么集群内容器的管理都将失效

Master节点上运行着以下一组关键进程:

  • [ ] Kubernetes API Server (kube-apiserver):提供了HTTP Rest接口的关键服务进程,是Kubernetes里所有资源的增、删、改、查等操作的唯一入口,也是集群控制的入口进程
  • [ ] Kubernetes Controller Manager (kube-controller-manager):Kubernetes里所有的资源对象的自动化控制中心
  • [ ] Kubernetes Scheduler (kube-scheduler):负责资源调度(Pod调度)的进程

另外在Master节点上还需要启动一个etcd服务,因为Kubernetes里的所有资源对象的数据全部是保存在etcd

 

Kubernetes Node介绍

Node介绍 除了Master,集群中其他机器被称为Node节点,每个Node都会被Master分配一些工作负载Docker容器,当某个Node宕机时,其上的工作负载会被Master自动转移到其他节点上去。

每个Node节点上都运行着以下一组关键进程。

  • [x] kubelet负责Pod对应容器的创建、停止等任务,同时与Master节点密切协作,实现集群管理的基本功能
  • [x] kube-proxy实现Kubernetes Service的通信与负载均衡机制的重要组件。
  • [x] Docker Engine(Docker)Docker引擎,负责本机的容器创建和管理工作。

Kubernetes 中Master与Node工作内容

在集群管理方面,Kubernets将集群中的机器划分为一个Master节点和一群工作节点(Node),其中,在Master节点上运行着集群管理相关的一组进程kube-apiserver、kube-controller-manager和kube-scheduler,这些进程实现了整个集群的资源管理、Pod调度、弹性收缩、安全控制、系统监控和纠错等管理功能,并且都是全自动完成的。Node作为集群中的工作节点,运行真正的应用程序,在Node上Kubernetes管理的最小运行单元是Pod。Node上运行着Kubernetes的kubelet、kube-proxy服务进程,这些服务进程负责Pod创建、启动、监控、重启、销毁、以及实现软件模式的负载均衡 

2. Kubernetes Pod

Pod 介绍

每个Pod都有一个特殊的被称为根容器Pause容器。Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器 

为什么Kubernetes会设计出一个全新的Pod概念,并且有这样特殊的结构?

原因一:Pause容器作为Pod根容器,以它的状态代表整个容器组的状态 原因二: Pod里的多个业务容器共享Pause容器的IP,共享Pause容器挂接的Volume

Kubernetes为每个Pod分配唯一IP的地址,称之为Pod IP,一个Pod里的多个容器共享Pod IP。Kubernetes要求底层网络支持集群内任意两个Pod之间的TCP/IP的直接通讯,采用虚拟二层网络技术来实现,一个Pod里的容器与另外主机上的Pod容器能够直接通信。

静态Pod&普通Pod

普通的Pod:

普通Pod:一旦被创建,就会被放入到etcd中存储,随后会被Kubernetes Master调度到某个具体的Node上并进行绑定(Binding),随后该Pod 被对应的Node上的kubelet进程实例化成一组相关的docker容器运行起来。     当Pod里的某个容器停止时,Kubernetes会自动检测到这个问题并且重新启动这个Pod (重启Pod里的所有容器),如果Pod所在的Node宕机,则会将这个Node上所有的Pod从新调度到其他节点上。

静态Pod (STatic Pod)
静态Pod不存放在Kubernetes的etcd存储里,而是存放在某个具体的Node上的文件中,并且只在此Node上启动运行。

静态Pod是由kubelet进行管理的仅存在于特定Node上的Pod。他们不能通过API Server进行管理,无法与ReplicationController(RC)、Deployment、或者DaemonSet进行关联,并且kubelet也无法对它们进行健康检查。静态Pod总是由kubelet进行创建的,并且总是在kubelet所在的Node上运行的

创建静态Pod有两种方式:配置文件方式和HTTP方式

1.配置文件方式

首先,需要设置kubelet的启动参数"config",指定kubelet需要监控的配置文件所在的目录,kubelet会定期扫描该目录,并根据该目录中的*.yaml*.json文件进行创建操作

部署静态Pod

1.选择一个节点来运行静态pod

[root@abcdocker ~] $ ssh master

2.选择一个目录,例如/etc/kubelet.d,把web服务器的pod定义文件放在这个目录下,例如/etc/kubelet.d/static-web.yaml:

[root@my-node1 ~] $ mkdir /etc/kubelet.d/
[root@my-node1 ~] $ cat <<EOF >/etc/kubelet.d/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
EOF

3.配置节点上的kubelet使用这个目录,kubelet启动时增加--pod-manifest-path=/etc/kubelet.d/参数。如果是Fedora系统,在Kubelet配置文件/etc/kubernetes/kubelet中添加下面这行:

...
KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/"
...

4.重启kubelet

[root@abcdocker ~]  systemctl restart kubelet

提示:由于Pod无法通过API Server直接进行管理,所以Master节点尝试删除这个Pod,将会使其状态变成Pending状态,且不会被删除

Endpoint

Pod的IP加上这里的容器端口(container Port),就组成了一个全新的概念---Endpoint 它代表着此Pod里的一个服务进程的对外通讯地址。一个Pod也存在着多个Endpoint的情况,比如我们把Tomcat定义为一个Pod时,可以对外暴露端口与服务端口这两个Endpoint

Event

Event是一个事件记录,记录事件的最早生成时间、最后重现时间、重复次数、发起者、类型,以及导致此事件的原因等众多信息。Event通常会关联到某个具体的资源上,是排查故障的重要参考,Node描述信息包含了Event,而Pod同样有Event记录。

当我们发现某个Pod迟迟无法创建时,我们就可以用kubectl describe pod [Pod名称]来查看,定位问题

演示:

$ 使用kubectl get pod 可以查到当前Pod数

[root@master ~]# kubectl get pod

NAME                                READY     STATUS              RESTARTS   AGE

nginx-deployment-5c6b9976cc-2qbkr   0/1       ContainerCreating   0          14s

nginx-deployment-5c6b9976cc-bqtvp   0/1       ContainerCreating   0          14s

nginx-deployment-5c6b9976cc-ttdrz   0/1       ContainerCreating   0          14s

 

$ 使用kubetctl describe pod [Pod名称]可以看到Pod详细信息

[root@master ~]# kubectl describe pod nginx-deployment-5c6b9976cc-2qbkr

 

Events:

  Type     Reason                  Age               From               Message

  ----     ------                  ----              ----               -------

  Normal   Scheduled               35s               default-scheduler  Successfully assigned default/nginx-deployment-5c6b9976cc-2qbkr to master

  Warning  FailedCreatePodSandBox  6s (x2 over 28s)  kubelet, master    Failed create pod sandbox: rpc error: code = Unknown desc = failed pulling image "gcr.io/google_containers/pause-amd64:3.0": Error response from daemon: Get https://gcr.io/v1/_ping: dial tcp 74.125.203.82:443: getsockopt: connection timed out

一个完整的Pod,正常创建没有错误如下

$ 显示一个Pod完整信息

[root@master ~]# kubectl describe pod tomcat-6755d5587c-nfjst

Name:           tomcat-6755d5587c-nfjst

Namespace:      default

Node:           master/192.168.60.24

Start Time:     Wed, 18 Jul 2018 16:29:37 +0800

Labels:         app=abcdocker

                pod-template-hash=2311811437

Annotations:    <none>

Status:         Running

IP:             172.17.0.2

Controlled By:  ReplicaSet/tomcat-6755d5587c

Containers:

  tomcat:

    Container ID:   docker://415acd35b6d4ed3effd26e2d9a958a56e83619243b0216690e0573a6c079bf1f

    Image:          daocloud.io/library/tomcat

    Image ID:       docker-pullable://daocloud.io/library/tomcat@sha256:1c39cc2e882b4169199888

    Port:           80/TCP

    Host Port:      0/TCP

    State:          Running

      Started:      Wed, 18 Jul 2018 16:33:18 +0800

    Ready:          True

    Restart Count:  0

    Environment:    <none>

    Mounts:

      /var/run/secrets/kubernetes.io/serviceaccount from default-token-cbkfr (ro)

Conditions:

  Type              Status

  Initialized       True

  Ready             True

  ContainersReady   True

  PodScheduled      True

Volumes:

  default-token-cbkfr:

    Type:        Secret (a volume populated by a Secret)

    SecretName:  default-token-cbkfr

    Optional:    false

QoS Class:       BestEffort

Node-Selectors:  <none>

Tolerations:     <none>

Events:          <none>

 

Pod基本用法

Pod的基本用法为:Pod 可以创建一个或多个容器组合而成

创建一个名为nginx-deploymentPod只由一个容器组成
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx   ##容器名称
        image: daocloud.io/library/nginx:1.13.0-alpine  #镜像地址
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80

另一种场景,当nginx容器和tomcat容器应用为紧耦合的关系,应该组合成一个整体对外提供服务时,应将这两个容器打包为一个Pod 

配置nginx和tomcat yaml文件如下下

[root@master test]# cat abcdocker.yaml

apiVersion: apps/v1beta2

kind: Deployment

metadata:

  name: abcdocker-pod

spec:

  replicas: 1

  selector:

    matchLabels:

      app: test

  template:

    metadata:

      labels:

        app: test

    spec:

      containers:

      - name: abcdocker-nginx-docker

        image: daocloud.io/library/nginx:1.13.0-alpine

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 80

      - name: abcdocker-tomcat-docker

        image: daocloud.io/library/tomcat:8.5.21-jre8-alpine

        imagePullPolicy: IfNotPresent

        ports:

        - containerPort: 8080

 

[root@master test]# kubectl create -f abcdocker.yaml

 

##参数解释

查看Pod运行状态

 

我们可以看到READY信息为2/2,表示Pod中的两个容器都成功运行了 (状态Running)

我们可以在master上查看docker上的容器 

 

查看Pod的详细信息,我们可以看到两个容器的定义及创建的过程 Event信息事件

[root@master ~]# kubectl describe pod abcdocker-pod-dc6b86f8d-7tjwp
Name:           abcdocker-pod-dc6b86f8d-7tjwp
Namespace:      default
Node:           master/192.168.60.24
Start Time:     Fri, 31 Aug 2018 11:06:02 +0800
Labels:         app=test
                pod-template-hash=872642948
Annotations:    <none>
Status:         Running
IP:             172.16.219.106
Controlled By:  ReplicaSet/abcdocker-pod-dc6b86f8d
Containers:
  abcdocker-nginx-docker:  ## 容器名称
    Container ID:   docker://63d038a53c613e0dfdb62df957035f0ab54cc5428461c33f9cbcee0118815619
    Image:          daocloud.io/library/nginx:1.13.0-alpine   ##容器镜像
    Image ID:       docker-pullable://daocloud.io/library/nginx@sha256:5c36f962c506c379bd63884976489c9c5e700c1496a6e8ea13dc404b1d258f76
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 31 Aug 2018 11:06:17 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-c6m5g (ro)
  abcdocker-tomcat-docker:  
    Container ID:   docker://42e0e6ee79860c5dac6a9103c549bd47422e8044f2c57046f6ad4dcca346f743
    Image:          daocloud.io/library/tomcat:8.5.21-jre8-alpine
    Image ID:       docker-pullable://daocloud.io/library/tomcat@sha256:96a11198cf980995e61d906ba65b1c86934ffc4c7e9381157d2aebd8981a4480
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Fri, 31 Aug 2018 11:07:20 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-c6m5g (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-c6m5g:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-c6m5g
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     <none>
Events:          <none>

Pod的配置管理 ConfigMap

应用部署的一个最佳实践是讲应用所需的配置信息与程序进行分离,这样可以使得应用程序被更好地复用,通过不同的配置也能实现灵活的功能。将应用打包为容器镜像后,可以通过环境变量或者外挂文件的方式在创建容器时进行配置注入,但在大规模容器集群中,对多个容器进行不同的配置将变得非常复杂。从kubernetes1.2开始提供了一套同意的应用配置管理方案----ConfigMap(资源对象)

ConfigMap概述

ConfigMap供容器使用的典型用法如下

  • 生成为容器内的环境变量
  • 设置容器的启动命令的启动参数 (需要设置为环境变量)
  • 以Volume的形式挂载为容器内部的文件或目录

ConfigMap以一个或多个key:value的形式保存在Kubernetes系统中供应用使用,既可以用于表示一个变量的值(例如apploglevel=info),也可以用于表示一个完整配置文件的内容(server.xml=<?xml..>..)

可以通过yaml配置文件或者直接使用kubectl create configmap来创建ConfigMap

创建ConfigMap

创建ConfigMap的方式有4种:

  • 通过直接在命令行中指定configmap参数创建,即--from-literal
  • 通过指定文件创建,即将一个配置文件创建为一个ConfigMap--from-file=<文件>
  • 通过指定目录创建,即将一个目录下的所有配置文件创建为一个ConfigMap,--from-file=<目录>
  • 事先写好标准的configmap的yaml文件,然后kubectl create -f 创建

1、使用yaml文件创建ConfigMap

==演示: 通过定义yaml配置文件方式创建ConfigMap==

cat > configmap-test.yaml << EOF
apiVersion: v1
kind: ConfigMap
metadata:
  name: test-configmap
data:
  key1: abcdocker1
  keydir: /var/data
EOF
 
# name: configmap名称
data.key1: key1 对应的值
data.keydir: keydir对应的挂载目录
 
 
创建并查看Configmap
[root@master configmap]# kubectl create -f configmap-test.yaml
configmap/test-configmap created
[root@master configmap]# kubectl get configmaps
NAME             DATA      AGE
test-configmap   2         5s
# 这里我们可以看到创建了2data的数据,就是我们上面定义的
 
 
查看创建好的configMap
[root@master configmap]# kubectl describe configmaps test-configmap
Name:         test-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>
 
Data
====
key1:
----
abcdocker1
keydir:
----
/var/data
Events:  <none>
 
# Data下面是对应的我们上面定义的key和挂载的目录

2、使用--from-file参数创建ConfigMap

==演示: 通过--from-file参数从文件中进行创建,可以指定key的名称,也可以在一个命令行中创建多个key的ConfigMap==

语法格式
 
kubectl create configmap Name --from-file=[key=]source --from-file=[key=]source

例:当前目录下含有配置文件server.xml,可以创建一个包含该文件内容的ConfigMap

kubectl create configmap test-server.xml --from-file=server.xml

例:当前configfiles下有2个配置文件,创建一个configmap包含2个文件内容

kubectl create configmap two-conf --from-file=configfiles

3、使用--from-literal创建ConfigMap

==使用--from-literal参数进行创建的示例如下:==

kubectl create configmap test-configmap --from-literal=loglevel=info --from-literal=appdatadir=/var/data
 
[root@master ~]# kubectl describe test-configmap
Name:         test-configmap
Namespace:    default
Labels:       <none>
Annotations:  <none>
 
Data
====
appdatadir:     9 bytes
loglevel:       4 bytes
 
Events:  <none>

容器应用对ConfigMap的使用有以下两种方法

  1. 通过环境变量获取ConfigMap中的内容
  2. 通过Volume挂载的方式将ConfigMap中的内容挂载为容器内部的文件或目录

Pod中使用ConfigMap

(1) 通过环境变量方式使用ConfigMap

首先我们需要创建ConfigMap

1.创建ConfigMap
[root@master configmap]# cat configmap-test-1.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: abcdocker-configmap
data:
  keyinfo: www.abcdocker.com
  abcdockerDir: /var/data
 
kubectl create -f configmap-test-1.yaml
 
 
2.创建pod进行引用
[root@master configmap]# cat configmap-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: abcdocker-pod
spec:
  containers:
    - name: configmap-pod
      image: busybox
      command: [ "/bin/sh", "-c", "env | grep config" ]
      env:
        - name: configmapPod
          valueFrom:
            configMapKeyRef:
              name: abcdocker-configmap
              key: keyinfo
        - name: configmapDir
          valueFrom:
            configMapKeyRef:
              name: abcdocker-configmap
              key: abcdockerDir
  restartPolicy: Never
 
==================相关参数解释===================
      env:
        - name: configmapPod    ##定义环境变量名称
          valueFrom:            #key "keyinfo对应的值"
         configMapKeyRef:                     name: abcdocker-configmap     ##环境变量的值取自哪(上面创建的configmap名称)
              key: keyinfo      #configmap里对应的key
        - name: configmapDir
          valueFrom:
            configMapKeyRef:
              name: abcdocker-configmap
              key: abcdockerDir
==================================================
 
kubectl create -f configmap-pod.yaml

查看我们创建好的configmap

验证

使用命令查看所有Pod
[root@master configmap]# kubectl get pod --show-all
Flag --show-all has been deprecated, will be removed in an upcoming release
NAME                             READY     STATUS      RESTARTS   AGE
abcdocker-pod                    0/1       Completed   0          3m

查看Pod日志

从kubernetes1.6开始,引用了一个新的字段envFrom实现Pod环境内将ConfigMap中所有定义的key=value自动生成为环境变量

[root@master configmap]# cat configmap-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: abcdocker-pod
spec:
  containers:
    - name: configmap-pod
      image: busybox
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - configMapRef:
          name: abcdocker-configmap  ##根据configmap中自动生成key=value环境变量
  restartPolicy: Never

通过这个定义,在容器内部将会自动生成如下环境配置需要说明的是,环境变量的名称手POSIX命名规范([a-zA-Z][a-zA-Z0-9])约束,不能以数字开头。如果包含非法字符,则系统将跳过该条环境变量的创建,并记录一个Event来描述环境变量无法生成,但不阻止Pod的启动

(2) 通过volumeMount使用ConfigMap

在本例子中包含了1个配置文件的定义 server.xml

1.创建ConfigMap
 
[root@master configmap]# cat configmap-tomcat-server.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: tomcat-server-config
data:
  server.xml: |
    <?xml version='1.0' encoding='utf-8'?>
      <Server port="8005" shutdown="SHUTDOWN">
      <Listener className="org.apache.catalina.startup.VersionLoggerListener" />
      <!--APR library loader. Documentation at /docs/apr.html -->
      <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
      <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
      <Listener className="org.apache.catalina.core.JasperListener" />
      <!-- Prevent memory leaks due to use of particular java/javax APIs-->
      <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
      <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
      <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
      <GlobalNamingResources>
        <Resource name="UserDatabase" auth="Container"
                  type="org.apache.catalina.UserDatabase"
                  description="User database that can be updated and saved"
                  factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
                  pathname="conf/tomcat-users.xml" />
      </GlobalNamingResources>
      <Service name="Catalina">
        <Executor name="tomcatThreadPool" namePrefix="catalina-exec-"
            maxThreads="500" minSpareThreads="50" prestartminSpareThreads="true" />
        <Connector executor="tomcatThreadPool" port="8080" protocol="org.apache.coyote.http11.Http11NioProtocol"
                   connectionTimeout="20000"
                   redirectPort="8443"
                   enableLookups="false"
                   maxPostSize="10485760"
                   URIEncoding="UTF-8"
                   disableUploadTimeout="true"
                   maxConnections="10000"
                   SSLEnabled="false"/>
        <Engine name="Catalina" defaultHost="localhost">
          <Realm className="org.apache.catalina.realm.LockOutRealm">
            <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
                   resourceName="UserDatabase"/>
          </Realm>
          <Host name="localhost"  appBase="webapps"
                unpackWARs="true" autoDeploy="true">
            <Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
                   prefix="localhost_access_log." suffix=".txt"
                   pattern="%h %l %u %t &quot;%r&quot; %s %b" />
          </Host>
          <Context path="" docBase="/tomcat/webapps" debug="0" reloadable="true" crossContext="true"/>
        </Engine>
       </Service>
     </Server>
 
 

查看

[root@master configmap]# kubectl get configmaps tomcat-server-config
NAME                   DATA      AGE
tomcat-server-config   1         13s
 

查看详细信息

[root@master configmap]# kubectl describe configmaps tomcat-server-config
Name:         tomcat-server-config
Namespace:    default
Labels:       <none>
Annotations:  <none>
 
Data
====
server.xml:
----
<?xml version='1.0' encoding='utf-8'?>
  <Server port="8005" shutdown="SHUTDOWN">
  <Listener 
.....
 
 
 

2. 引用ConfigMap

Pod中的定义,将文件以mount挂载到容器内部定义的目录中去。Pod配置文件如下
 
 
[root@master configmap]# cat test.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - image: busybox
        imagePullPolicy: IfNotPresent
        name: tomcatpod
        volumeMounts:
        - mountPath: /tmp/server.xml
          name: serverxml
          subPath: server.xml
        ports:
        - containerPort: 8080
        command: ["tail", "-f", "/dev/null"]
      volumes:
      - name: serverxml
        configMap:
          name: tomcat-server-config
          items:
          - key: server.xml
            path: server.xml
 
kubectl create -f test.yaml        
===================参数解释===============
        volumeMounts:
        - mountPath: /tmp/server.xml  ##挂在到容器内的目录
          name: serverxml     #挂载名称(需要和volume的名称对应上)
          subPath: server.xml   #不加subPath会替换整个目录
        ports:
        - containerPort: 8080
        command: ["tail", "-f", "/dev/null"]
      volumes:
      - name: serverxml         #volumemount名称
        configMap:
          name: tomcat-server-config   #创建的configmap名称
          items:
          - key: server.xml     #对应的key
            path: server.xml    #挂载到目录的key名称
####################################
 
需要注意的是,不可以光mount挂载,需要执行命令让容器在前台运行!

验证 登陆容器可以在tmp目录下看到我们的server.xml

如果在引用ConfigMap时不指定items,则使用volumeMount方式在容器内的目录中为每个item生成一个文件夹为key的文件

[root@master configmap]# cat test_vo.yaml
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: abcdocker-pod1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tomcat
  template:
    metadata:
      labels:
        app: tomcat
    spec:
      containers:
      - image: busybox
        imagePullPolicy: IfNotPresent
        name: tomcatpod
        volumeMounts:
        - mountPath: /tmp/server.xml
          name: serverxml
          subPath: server.xml
        ports:
        - containerPort: 8080
        command: ["tail", "-f", "/dev/null"]
      volumes:
      - name: serverxml
        configMap:
          name: tomcat-server-config

验证

ConfigMap小结 使用ConfigMap的限制条件如下

  • ConfigMap必须在Pod之前创建
  • ConfigMap受Namespace限制,只有处于相同Namespace中的Pod可以引用它
  • ConfigMap中的配额管理还未能实现
  • Kubelet只可以支持可以被API Server管理的Pod使用ConfigMap。kubelet在本Node上通过 --manifest-url或--config自动创建的静态Pod将无法引用ConfigMap
  • 在Pod对ConfigMap进行挂载volumeMount操作时,容器内部只能挂载"目录",无法挂载为文件。在挂载到容器内部后,目录中将包含ConfigMap定义的每个item,如果该目录下原来还有其他文件,则容器内的该目录将会被挂载的ConfigMap覆盖。如果应用程序需要保留原来的其他文件,则需要进行额外的处理。可以将ConfigMap挂载到容器内部的临时目录,再通过启动脚本将配置文件复制或者链接到(cp link)应用所用的实际配置目录下
  • 需要注意的是,容器不可以光mount挂载,需要执行命令让容器在前台运行!
  • 需要在挂载下面添加subPath,否则将会替换整个目录

 

 

 

猜你喜欢

转载自www.cnblogs.com/Zyuhao/p/11326287.html