kubernetes 实践之Pod

首先看一个例子,Guestbook,对k8s对于容器应用的基本操作和用法进行理解,本例通过pod 、RC、Service等资源对象创建完成,架构图:

①、创建redis-master的RC和Service

[[email protected]_master php-redis]# cat redis-master-controller-RC.yaml
apiVersion: v1
kind: ReplicationController                           
metadata:
    name: redis-master                #rc的名称             
    labels:                                    
        name: redis-master              #rc的标签
spec:
    replicas: 1                     #pod的副本数量  
    selector:
        name: redis-master                #选择管理的pod (这里是标签名称)
    template:
        metadata:
            labels:
                name: redis-master            #pod的标签名称,名称与上面的seletor一样         
        spec:                         #pod内的容器属性信息
            containers:
            - name: master                 
              image: docker.io/kubeguide/redis-master
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 6379                

[[email protected]_master php-redis]# cat redis-master-controller-Service.yaml
apiVersion: v1
kind: Service
metadata:
    name: redis-master            
    labels:
        name: redis-master          
spec:
    ports:
      - port: 6379                #自定义指定的对外提供服务的端口
        targetPort: 6379             #pod里容器暴露的端口
    selector:
        name: redis-master            #选择的pod标签

执行命令创建

kubectl create -f redis-master-controller-RC.yaml -f  redis-master-controller-Service.yaml

②、创建redis-slave RC和Service

[[email protected]_master php-redis]# cat redis-slave-controller-RC.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: docker.io/kubeguide/guestbook-redis-slave
              imagePullPolicy: IfNotPresent
              env:                          #这里表示从slave-pod的环境变量中获取redis-master服务的ip地址信息
              - name: GET_HOSTS_FROM
                value: env
              ports:
              - containerPort: 6379

[[email protected]_master php-redis]# cat redis-slave-controller-Service.yaml
apiVersion: v1
kind: Service
metadata:
    name: redis-slave
    labels:
        name: redis-slave
spec:
    ports:
      - port: 6379
    selector:
        name: redis-slave

说明:

  在创建redis-slave pod时,系统将自动在容器内部生成之前已经创建好的redis-master service相关的环境变量,所以redis-slave应用程序redis-server 可以直接使用环境变量 REDIS_MASTER_SERVICE_HOST来获取redis-master服务的ip地址,如果不设置该env,则将使用redis-master服务的名称“redis-master”来访问他,使用DNS服务发现的方式,需要配置skydns服务

查看该slave的环境变量如下

[[email protected]_master php-redis]# kubectl get pods
NAME                 READY     STATUS    RESTARTS   AGE
frontend-7kkwx       1/1       Running   0          1h
frontend-9hbct       1/1       Running   0          1h
frontend-vpq8c       1/1       Running   0          1h
redis-master-0k0m2   1/1       Running   0          2h
redis-slave-c5nlk    1/1       Running   0          1h
redis-slave-qr0pn    1/1       Running   0          1h

[[email protected]_master php-redis]# kubectl exec redis-slave-c5nlk env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=redis-slave-c5nlk
GET_HOSTS_FROM=env
KUBERNETES_PORT=tcp://10.254.0.1:443
KUBERNETES_PORT_443_TCP_ADDR=10.254.0.1
REDIS_MASTER_SERVICE_HOST=10.254.85.180
KUBERNETES_SERVICE_PORT=443
REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.254.0.1:443
REDIS_MASTER_PORT_6379_TCP=tcp://10.254.85.180:6379
REDIS_MASTER_PORT_6379_TCP_PORT=6379
REDIS_MASTER_PORT_6379_TCP_ADDR=10.254.85.180
KUBERNETES_SERVICE_HOST=10.254.0.1
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
REDIS_MASTER_SERVICE_PORT=6379
REDIS_MASTER_PORT=tcp://10.254.85.180:6379
REDIS_VERSION=3.0.3
REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.0.3.tar.gz
REDIS_DOWNLOAD_SHA1=0e2d7707327986ae652df717059354b358b83358
HOME=/root

创建

kubectl create -f redis-slave-controller-RC.yaml -f  redis-slave-controller-Service.yaml

③、创建frontend RC和Service

[[email protected]_master php-redis]# cat 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: docker.io/kubeguide/guestbook-php-frontend
              imagePullPolicy: IfNotPresent
              env:
              - name: GET_HOSTS_FROM
                value: env
              ports:
              - containerPort: 80

[[email protected]_master php-redis]# cat frontend-Service.yaml
apiVersion: v1
kind: Service
metadata:
    name: frontend
    labels:
        name: frontend
spec:
    type: NodePort
    ports:
      - port: 80
        nodePort: 30001
    selector:
        name: frontend

注:

  容器的配置中加了环境变量,意思是从环境变量中获取 redis-master和redis-slave服务的ip地址信息

创建

kubectl create -f frontend-controller.yaml -f  frontend-Service.yaml

查看所有信息

[[email protected]_master ~]# kubectl get pods -o wide
NAME                 READY     STATUS    RESTARTS   AGE       IP          NODE
frontend-7kkwx       1/1       Running   0          2h        10.1.34.3   192.168.132.136
frontend-9hbct       1/1       Running   0          2h        10.1.20.4   192.168.132.149
frontend-vpq8c       1/1       Running   0          2h        10.1.34.4   192.168.132.136
redis-master-0k0m2   1/1       Running   0          3h        10.1.20.2   192.168.132.149
redis-slave-c5nlk    1/1       Running   0          2h        10.1.34.2   192.168.132.136
redis-slave-qr0pn    1/1       Running   0          2h        10.1.20.3   192.168.132.149
[[email protected]_master ~]# kubectl get rc -o wide
NAME           DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)                                     SELECTOR
frontend       3         3         3         2h        frontend       docker.io/kubeguide/guestbook-php-frontend   name=frontend
redis-master   1         1         1         3h        master         docker.io/kubeguide/redis-master             name=redis-master
redis-slave    2         2         2         2h        slave          docker.io/kubeguide/guestbook-redis-slave    name=redis-slave
[[email protected]_master ~]# kubectl get service -o wide
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE       SELECTOR
frontend       10.254.51.228   <nodes>       80:30001/TCP   2h        name=frontend
kubernetes     10.254.0.1      <none>        443/TCP        272d      <none>
redis-master   10.254.85.180   <none>        6379/TCP       3h        name=redis-master
redis-slave    10.254.70.40    <none>        6379/TCP       2h        name=redis-slave
[[email protected]_master ~]# kubectl describe service redis-master redis-slave frontend
Name:            redis-master
Namespace:        default
Labels:            name=redis-master
Selector:        name=redis-master
Type:            ClusterIP
IP:            10.254.85.180
Port:            <unset>    6379/TCP
Endpoints:        10.1.20.2:6379
Session Affinity:    None
No events.

Name:            redis-slave
Namespace:        default
Labels:            name=redis-slave
Selector:        name=redis-slave
Type:            ClusterIP
IP:            10.254.70.40
Port:            <unset>    6379/TCP
Endpoints:        10.1.20.3:6379,10.1.34.2:6379
Session Affinity:    None
No events.

Name:            frontend
Namespace:        default
Labels:            name=frontend
Selector:        name=frontend
Type:            NodePort
IP:            10.254.51.228
Port:            <unset>    80/TCP
NodePort:        <unset>    30001/TCP
Endpoints:        10.1.20.4:80,10.1.34.3:80,10.1.34.4:80
Session Affinity:    None
No events.

访问node节点的30001端口,可看到界面,添加和查询都是经过redis,并实时显示出来

pod深入

yaml格式的pod定义文件完整内容

apiVersion: v1                    #必选,版本号,例如v1,版本号必须可以用 kubectl api-versions 查询到 .
kind: Pod                      #必选,Pod
metadata:                      #必选,元数据
  name: string                    #必选,Pod名称
  namespace: string               #可以不选,Pod所属的命名空间,默认为"default"
  labels:                       #自定义标签
    - name: string                 #自定义容器的标签名字
  annotations:                           #自定义注释列表
    - name: string
spec:                            #必选,Pod中容器的详细定义
  containers:                       #必选,Pod中容器列表
  - name: string                        #必选,容器名称,需符合RFC 1035规范
    image: string                       #必选,容器的镜像名称或镜像地址
    imagePullPolicy: [ Always|Never|IfNotPresent ]  #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
    command: [string]               #容器的启动命令列表,如不指定,使用打包时使用的启动命令
    args: [string]                     #容器的启动命令参数列表
    workingDir: string                     #容器的工作目录
    volumeMounts:                 #挂载到容器内部的存储卷配置
    - name: string                 #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
      mountPath: string                 #存储卷在容器内mount的绝对路径,应少于512字符
      readOnly: boolean                 #是否为只读模式
    ports:                      #需要暴露的端口库号列表
    - name: string                 #端口的名称
      containerPort: int                #容器需要监听的端口号
      hostPort: int                    #容器所在主机需要监听的端口号,默认与Container相同
      protocol: string                  #端口协议,支持TCP和UDP,默认TCP
    env:                          #容器运行前需设置的环境变量列表
    - name: string                    #环境变量名称
      value: string                   #环境变量的值
    resources:                          #资源限制和请求的设置
      limits:                       #资源限制的设置
        cpu: string                   #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
        memory: string                  #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
      requests:                         #资源请求的设置
        cpu: string                   #Cpu请求,容器启动的初始可用数量
        memory: string                    #内存请求,容器启动的初始可用数量
    livenessProbe:                    #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
      exec:                     #对Pod容器内检查方式设置为exec方式
        command: [string]               #exec方式需要制定的命令或脚本
      httpGet:                    #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
        path: string
        port: number
        host: string
        scheme: string
        HttpHeaders:
        - name: string
          value: string
      tcpSocket:            #对Pod内个容器健康检查方式设置为tcpSocket方式
         port: number
       initialDelaySeconds: 0       #容器启动完成后首次探测的时间,单位为秒
       timeoutSeconds: 0          #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
       periodSeconds: 0           #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
       successThreshold: 0
       failureThreshold: 0
       securityContext:
         privileged: false
    restartPolicy: [Always | Never | OnFailure] #Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
    nodeSelector: obeject         #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
    imagePullSecrets:         #Pull镜像时使用的secret名称,以key:secretkey格式指定
    - name: string
    hostNetwork: false            #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
    volumes:                  #在该pod上定义共享存储卷列表
    - name: string              #共享存储卷名称 (volumes类型有很多种)
      emptyDir: {}              #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
      hostPath: string            #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
        path: string                #Pod所在宿主机的目录,将被用于同期中mount的目录
      secret:                 #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
        scretname: string
        items:
        - key: string
          path: string
      configMap:                      #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
        name: string
        items:
        - key: string
          path: string

docker容器运行以一个前台命令运行,但是有些应用程序无法改造为前台应用,此时需要使用开源工具supervisor辅助进行前台运行的功能

supervisor提供了一种可以同时启动多个后台应用,并保持superviosr自身在前台执行的机制,可以满足k8s对容器的启动要求

  • 一、pod的基本用法

  pod由一个或多个容器组成,上述例子中,可以将redis容器和frontend容器放到一个pod中,如下

[[email protected]_master php-redis]# cat frontend-localredis-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: redis-php
  namespace: kube-system
  labels:
    name: redis-php
spec:
  containers:
  - name: frontend
    image: docker.io/kubeguide/guestbook-php-frontend
    ports:
    - containerPort: 80
  - name: redis
    image: docker.io/kubeguide/redis-master
    ports:
    - containerPort: 6379

[[email protected]_master php-redis]# kubectl  create -f frontend-localredis-pod.yaml  

[[email protected]_master php-redis]# kubectl get pod --namespace=kube-system -o wide
NAME                 READY     STATUS    RESTARTS   AGE       IP          NODE
kube-dns-v11-dtfxq   4/4       Running   30         7d        10.1.34.5   192.168.132.136
redis-php            2/2       Running   0          5m        10.1.20.5   192.168.132.149
[[email protected]_master php-redis]# kubectl describe pod redis-php --namespace=kube-system
Name:        redis-php
Namespace:    kube-system
Node:        192.168.132.149/192.168.132.149
Start Time:    Wed, 18 Jul 2018 20:13:01 +0800
Labels:        name=redis-php
Status:        Running
IP:        10.1.20.5
Controllers:    <none>
Containers:
  frontend:
    Container ID:        docker://0796e31721992a15dc465de5cbd2eb52674593564525982442996f8bfa484261
    Image:            docker.io/kubeguide/guestbook-php-frontend
    Image ID:            docker-pullable://docker.io/kubeguide/guestbook-php-[email protected]:195181e0263bcee4ae0c3e79352bbd3487224c0042f1b9ca8543b788962188ce
    Port:            80/TCP
    State:            Running
      Started:            Wed, 18 Jul 2018 20:13:30 +0800
    Ready:            True
    Restart Count:        0
    Volume Mounts:        <none>
    Environment Variables:    <none>
  redis:
    Container ID:        docker://7faf99750a540f7f13e2464d41a0d56059935cdf49692434396deba03b82bb56
    Image:            docker.io/kubeguide/redis-master
    Image ID:            docker-pullable://docker.io/kubeguide/redis-[email protected]:e11eae36476b02a195693689f88a325b30540f5c15adbf531caaecceb65f5b4d
    Port:            6379/TCP
    State:            Running
      Started:            Wed, 18 Jul 2018 20:13:42 +0800
    Ready:            True
    Restart Count:        0
    Volume Mounts:        <none>
    Environment Variables:    <none>
Conditions:
  Type        Status
  Initialized     True
  Ready     True
  PodScheduled     True
No volumes.
QoS Class:    BestEffort
Tolerations:    <none>
Events:
  FirstSeen    LastSeen    Count    From                SubObjectPath            Type        Reason        Message
  ---------    --------    -----    ----                -------------            --------    ------        -------
  5m        5m        1    {default-scheduler }                        Normal        Scheduled    Successfully assigned redis-php to 192.168.132.149
  3m        3m        1    {kubelet 192.168.132.149}    spec.containers{frontend}    Normal        Pulling        pulling image "docker.io/kubeguide/guestbook-php-frontend"
  3m        3m        1    {kubelet 192.168.132.149}    spec.containers{frontend}    Normal        Pulled        Successfully pulled image "docker.io/kubeguide/guestbook-php-frontend"
  3m        3m        1    {kubelet 192.168.132.149}    spec.containers{frontend}    Normal        Created        Created container with docker id 0796e3172199; Security:[seccomp=unconfined]
  3m        3m        1    {kubelet 192.168.132.149}    spec.containers{frontend}    Normal        Started        Started container with docker id 0796e3172199
  3m        3m        1    {kubelet 192.168.132.149}    spec.containers{redis}        Normal        Pulling        pulling image "docker.io/kubeguide/redis-master"
  3m        3m        1    {kubelet 192.168.132.149}    spec.containers{redis}        Normal        Pulled        Successfully pulled image "docker.io/kubeguide/redis-master"
  3m        3m        1    {kubelet 192.168.132.149}    spec.containers{redis}        Normal        Created        Created container with docker id 7faf99750a54; Security:[seccomp=unconfined]
  3m        3m        1    {kubelet 192.168.132.149}    spec.containers{redis}        Normal        Started        Started container with docker id 7faf99750a54

因为在同一个pod中,两个容器之间可以通过localhost互相通信(可通过进入pod进行telnet或者curl测试)

  • 二、静态pod

  静态pod是有kubelet进行管理的存在于特定node上的pod,静态pod不能通过api server进行管理,无法使用rc service deployment进行关联,并且kubelet无法对他们进行检查,静态pod总是有kubelet进行创建,并且总是在kubelet所在的node上运行

  创建静态pod的两种方式:配置文件和http

配置文件方式创建

  首先需要设置kubeclt的启动参数 “--config”,指定需要监控的配置文件所在的目录,kubelet会定期扫描该目录,并根据目录中的yaml或者json文件执行创建操作

如下:

[[email protected]_node1 kubernetes]# cat kubelet |grep KUBELET_ARGS    #修改配置文件
KUBELET_ARGS="--config=/etc/kubelet.d/ --cluster_dns=10.254.10.2 --pod_infra_container_image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
#重启服务[[email protected]_node1 kubernetes]# systemctl restart kubelet

#pod文件
[[email protected]_node1 kubernetes]# cat /etc/kubelet.d/static-web.yaml
apiVersion: v1
kind: Pod
metadata:
  name: static-web
  namespace: kube-system
  labels:
    name: static-web
spec:
  containers:
  - name: static-web
    image: nginx
    ports:
    - name: web
      containerPort: 80

#等待一会会自动创建容器
[[email protected]_node1 ~]# docker ps
CONTAINER ID        IMAGE          COMMAND                  CREATED             STATUS       PORTS   NAMES
a420210bcaf1        nginx          "nginx -g ‘daemon off"   8 minutes ago       Up 8 minutes         k8s_static-web.68ee0075_static-web-192.168.132.136_kube-system_11ce1c67a043c4209fb23dfb082b23da_14a4ab0e

#master节点查看
[[email protected]_master etc]# kubectl get pods --namespace=kube-system
NAME                         READY     STATUS    RESTARTS   AGE
kube-dns-v11-dtfxq           4/4       Running   30         7d
redis-php                    2/2       Running   0          42m
static-web-192.168.132.136   1/1       Running   0          2m

#注:删除kubelet.d目录下的yaml文件会,创建的容器会自动删除
  • 三、pod容器共享volume

  同一个pod内多个容器共享volume

  示例: 创建一个pod,包含两个容器,pod设置volume为app-logs,用于tomcat写日志,busybox读日志

[[email protected]_master pod_test]# cat pod-volume-applogs.yaml
apiVersion: v1
kind: Pod
metadata:
  name: volume-pod
  namespace: kube-system
  labels:
    name: volume-pod
spec:
  containers:
  - name: tomcat
    image: tomcat
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: app-logs
      mountPath: /usr/local/tomcat/logs/

  - name: busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["sh","-c","tail -f /logs/catalina*.log"]
    volumeMounts:
    - name: app-logs
      mountPath: /logs
  volumes:
  - name: app-logs
    emptyDir: {}

#设置 volume名为app-logs;类型为emptyDir,挂在到tomcat 容器的/usr/local/tomcat/logs目录,同时挂载到busybox容器内的/logs目录,tomcat启动时会向目录中写文件
  # busybox容器的启动命令为查看容器的日志

查看日志和相关文件

#查看日志
[[email protected]_master pod_test]# kubectl logs volume-pod -c busybox --namespace=kube-system
18-Jul-2018 13:29:48.498 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.32
18-Jul-2018 13:29:48.500 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jun 20 2018 19:50:35 UTC
18-Jul-2018 13:29:48.500 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.5.32.0
18-Jul-2018 13:29:48.501 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Linux
18-Jul-2018 13:29:48.501 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            3.10.0-514.26.2.el7.x86_64
18-Jul-2018 13:29:48.501 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          amd64
18-Jul-2018 13:29:48.501 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /usr/lib/jvm/java-8-openjdk-amd64/jre
18-Jul-2018 13:29:48.501 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           1.8.0_171-8u171-b11-1~deb9u1-b11
18-Jul-2018 13:29:48.515 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
18-Jul-2018 13:29:48.515 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /usr/local/tomcat
18-Jul-2018 13:29:48.515 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /usr/local/tomcat
18-Jul-2018 13:29:48.519 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/usr/local/tomcat/conf/logging.properties
18-Jul-2018 13:29:48.526 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
18-Jul-2018 13:29:48.526 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
18-Jul-2018 13:29:48.530 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.protocol.handler.pkgs=org.apache.catalina.webresources
18-Jul-2018 13:29:48.530 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dorg.apache.catalina.security.SecurityListener.UMASK=0027
18-Jul-2018 13:29:48.530 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dignore.endorsed.dirs=
18-Jul-2018 13:29:48.531 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/usr/local/tomcat
18-Jul-2018 13:29:48.532 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/usr/local/tomcat
18-Jul-2018 13:29:48.532 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/usr/local/tomcat/temp
18-Jul-2018 13:29:48.532 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent Loaded APR based Apache Tomcat Native library [1.2.17] using APR version [1.5.2].
18-Jul-2018 13:29:48.533 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR capabilities: IPv6 [true], sendfile [true], accept filters [false], random [true].
18-Jul-2018 13:29:48.533 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent APR/OpenSSL configuration: useAprConnector [false], useOpenSSL [true]
18-Jul-2018 13:29:48.547 INFO [main] org.apache.catalina.core.AprLifecycleListener.initializeSSL OpenSSL successfully initialized [OpenSSL 1.1.0f  25 May 2017]
18-Jul-2018 13:29:50.419 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
18-Jul-2018 13:29:50.818 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
18-Jul-2018 13:29:50.856 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
18-Jul-2018 13:29:50.867 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
18-Jul-2018 13:29:50.872 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 10254 ms
18-Jul-2018 13:29:50.952 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service [Catalina]
18-Jul-2018 13:29:50.952 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.32
18-Jul-2018 13:29:50.975 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/ROOT]
18-Jul-2018 13:29:55.132 WARNING [localhost-startStop-1] org.apache.catalina.util.SessionIdGeneratorBase.createSecureRandom Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [1,458] milliseconds.
18-Jul-2018 13:29:55.291 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/ROOT] has finished in [4,315] ms
18-Jul-2018 13:29:55.291 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/docs]
18-Jul-2018 13:29:55.367 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/docs] has finished in [76] ms
18-Jul-2018 13:29:55.367 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/examples]
18-Jul-2018 13:29:56.747 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/examples] has finished in [1,380] ms
18-Jul-2018 13:29:56.747 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/host-manager]
18-Jul-2018 13:29:57.305 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/host-manager] has finished in [558] ms
18-Jul-2018 13:29:57.317 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory [/usr/local/tomcat/webapps/manager]
18-Jul-2018 13:29:57.381 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [/usr/local/tomcat/webapps/manager] has finished in [75] ms
18-Jul-2018 13:29:57.401 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-8080"]
18-Jul-2018 13:29:57.419 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["ajp-nio-8009"]
18-Jul-2018 13:29:57.560 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 6687 ms

#获取日志文件
[[email protected]_master pod_test]# kubectl exec -it volume-pod -c tomcat --namespace=kube-system -- ls /usr/local/tomcat/logs
catalina.2018-07-18.log  host-manager.2018-07-18.log  localhost.2018-07-18.log    localhost_access_log.2018-07-18.txt  manager.2018-07-18.log

  • 四、pod的配置管理之ConfigMap

  将应用所需的配置信息与程序进行分离,可以使程序更好的复用,k8s提供了统一的集群配置管理方案-ConfigMap

ConfigMap用法

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

ConfigMap以一个或多个key:value的形式保存在k8s系统中供应用使用,既可以用于表示一个变量的值,也可以用于表示一个完整的配置文件内容,可以通过yaml配置文件或者直接使用kubectl create configmap命令行的方式来创建ConfigMap

yaml文件方式

  创建yaml文件然后执行create

[[email protected]_master configmap]# cat cm.appvars.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appvars
data:
  apploglevel: info        #这里value可以写一个配置文件的所有内容(如tomcat配置文件),
  appdatadir: /var/data/

[[email protected]_master configmap]# kubectl create -f cm.appvars.yaml
configmap "cm-appvars" created
[[email protected]_master configmap]# kubectl get configmap
NAME         DATA      AGE
cm-appvars   2         14s
[[email protected]_master configmap]# kubectl describe configmap cm-appvars
Name:        cm-appvars
Namespace:    default
Labels:        <none>
Annotations:    <none>

Data
====
appdatadir:    10 bytes
apploglevel:    4 bytes

命令行方式创建ConfigMap

  使用参数 --from-file或者--from-literal,一行命令中可以指定多个参数,示例

#通过--from-file从文件中创建,可以指定key的名称
kubectl create configmap NAME --from-file=[key=]source --from-file=[key=]source

#通过--from-file从目录中创建,该目录下的每个配置文件名都被设置为key,文件的内容被设置为value
kubectl create configmap NAME --from-file=config-files-dir

#--from-literal从文本中进行创建,直接指定为key#=value#创建为configmap
kubectl create configmap NAME --from-literal=key1=value1 --from-literal=key2=value2    #这里参照上面配置文件创建方式为: --from-literal=loglevel=info --from-literal=appdatadir=/var/data

容器应用对ConfigMap的使用方法

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

使用环境变量方式

#configmap创建
[[email protected]_master configmap]# cat cm.appvars.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-appvars          #configmap创建后的名称
data:
  apploglevel: info          #configmap里的key和value
  appdatadir: /var/data/

#创建一个pod,打印环境变量并销毁

[[email protected]_master configmap]# cat cm-testpod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: cm-test-pod
spec:
  containers:
  - name: cm-test
    image: busybox
    command: ["/bin/sh", "-c", "env|grep APP"]
    env:
    - name: APPLOGLEVEL            #定义环境变量名称
      valueFrom:                 #定义key "apploglevel"对应的值从哪里获取  
        configMapKeyRef:
          name: cm-appvars          #环境变量的值取自 cm-appvars这个configmap(文件名称?。。),这个configmap必须存在,且必须与要创建的此pod在同一个namespace      key: apploglevel          #key为apploglevel
    - name: APPDATADIR
      valueFrom:
        configMapKeyRef:
          name: cm-appvars
          key: appdatadir
  restartPolicy: Never            #重启策略(不被重启)

查看效果

[[email protected]_master configmap]# kubectl logs cm-test-pod      #这里为创建的pod的名称
APPDATADIR=/var/data/
APPLOGLEVEL=info

使用volumemount方式

configmap

pod的yaml文件

测试

限制条件

  • 五、pod的生命周期和重启策略

  • 六、pod健康检查

LivebessProbe 实现的三种方式

  • ExecAction: 在容器内执行一个命令,如果该命令的放回码为0,则表明容器健康

  • TCPSocketAction: 通过容器的ip地址和端口号执行tcp检查,如果能建立tcp连接,表明容器健康

  • HTTPGetAction: 通过容器的ip地址、端口号及路径调用http Get方法,如果响应的状态码大于等于200且小于等于400,则认为容器健康

必须条件

  • 七、pod调度

根据rc deployment创建pod时,可以再创建时给yaml文件添加配置,使pod定向调度到指定的node节点上去

#首先给每个node打上一些标签,语法如下
kubectl label nodes <node-name> <label-key>=<label-value>

示例:
kubectl label nodes 192.168.132.149  labels=node-149

#然后在rc或者deployment的yaml文件中的pod定义中加上nodeSelector设置 ,示例

spec:
      containers:
      - name: nginx
        image: docker.io/nginx
        ports:
        - containerPort: 80
      nodeSelector:
          labels: node-149    #上面创建的标签

如果给多个node定义了相同的标签,shceduler会根据调度算法从这些node中挑选一个可用的node进行调度;

如果指定了pod的nodeselector条件,且集群中不存在相应的标签,即便有其它可使用的node,pod也不会创建成功

  • 八、pod的扩容和缩容

利用rc的scale机制进行pod扩容缩容

#将redis-slave rc控制的pod数量由2变成3

kubectl scale rc redis-slace --replicas=3

HPA自动扩容

#例如以一个web为例,这里只指定了cpu request为200m 未设置limit上限的值
[[email protected]_master php-redis]# cat 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: docker.io/kubeguide/guestbook-php-frontend
              imagePullPolicy: IfNotPresent
              env:
              - name: GET_HOSTS_FROM
                value: env
              resources:
                 requests:
                     cpu: 200m
              ports:
              - containerPort: 80

#创建rc
[[email protected]_master php-redis]# kubectl create -f  frontend-controller.yaml 

#创建service
[[email protected]_master php-redis]# cat frontend-Service.yaml
apiVersion: v1
kind: Service
metadata:
    name: frontend
    labels:
        name: frontend
spec:
    type: NodePort
    ports:
      - port: 80
        nodePort: 30001
    selector:
        name: frontend

#接下来为RC创建一个HPA控制器
#扩容方法①
kubectl autoscale rc frontend --min=1 --max=10 --cpu-percent=50      #为rc名称为frontend的扩容

#扩容方法②
[[email protected]_master php-redis]# cat frontend-hpa.yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
    name: frontend
spec:
    scaleTargetRef
       apiVersion: v1
       kind: ReplicationController
       name: frontend
    minReplicas: 1
    maxReplicas: 10
    targetCPUUtilizationPercentage: 50

查看创建的hpa

kubectl get hpa

然后创建一个pod进行压力测试

#cat busybox-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: busybox

spec:
  containers:
  - name: busybox
    image: busybox
    command: ["sleep","3600"]

#创建pod
kubectl create -f busybox-pod.yaml

#登录容器,执行一个无限循环的wget命令来访问web服务
kubectl exec -ti busybox -- /bin/bash    
#while true;do wget -q -O- http://cluster ip >/dev/null;done

等待一段时间,观察hpa控制器搜集到的pod的使用率

#查看hpa
kubectl get hpa

#查看rc下 frontend副本的数量变化
kubectl get rc

#然后关掉循环,等一会再看pod副本的数量
  • 九、pod滚动升级

  滚动升级通过执行kubectl rolling-update命令一键完成,该命令创建了一个新的Rc,然后自动控制旧的rc中的pod副本数量逐渐减少到0,同时新的RC中的副本数量从0逐渐增加到目标值,最终实现pod升级。

  需要注意的是,新的rc和旧的rc要在同一个namespace

示例:在上面redis-master的基础上进行滚动升级

redis-master-controller-RC-v2.yaml

[[email protected]_master php-redis]# cat redis-master-controller-RC-v2.yaml
apiVersion: v1
kind: ReplicationController
metadata:
    name: redis-master-v2            #注意,rc的名字不能与旧的rc的名字相同
    labels:
        name: redis-master
        version: v2
spec:
    replicas: 1
    selector:
        name: redis-master-v2          #在select中至少有一个label与旧的rc的label的名字不同,以标识其为新的rc
        version: v2
    template:
        metadata:
            labels:
                name: redis-master-v2
                version: v2
        spec:
            containers:
            - name: master
              image: docker.io/kubeguide/redis-master:2.0
              imagePullPolicy: IfNotPresent
              ports:
              - containerPort: 6379

执行滚动升级

[[email protected]_master php-redis]# kubectl rolling-update redis-master -f redis-master-controller-RC-v2.yaml

#不使用配置文件进行滚动升级
 kubectl rolling-update redis-master --image=redis-master:latest

查看结果

[[email protected]_master php-redis]# kubectl rolling-update redis-master -f redis-master-controller-RC-v2.yaml
Created redis-master-v2
Scaling up redis-master-v2 from 0 to 1, scaling down redis-master from 1 to 0 (keep 1 pods available, don‘t exceed 2 pods)
Scaling redis-master-v2 up to 1
Scaling redis-master down to 0
Update succeeded. Deleting redis-master
replicationcontroller "redis-master" rolling updated to "redis-master-v2"

#查看rc
[[email protected]_master php-redis]# kubectl get rc -o wide
NAME              DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)                                     SELECTOR
frontend          3         3         3         13h       frontend       docker.io/kubeguide/guestbook-php-frontend   name=frontend
redis-master-v2   1         1         1         3m        master         docker.io/kubeguide/redis-master:latest      name=redis-master-v2,version=v2

回滚操作

#回滚,执行的时候出错,查看 kubectl rolling-update -h 查看一下说明
 kubectl rolling-update redis-master --image=redis-master --rollback

#此示例中执行如下进行回滚kubectl rolling-update redis-master redis-master-v2 --rollback

查看结果

[[email protected]_master php-redis]# kubectl rolling-update redis-master redis-master-v2 --rollback
Setting "redis-master" replicas to 1
Continuing update with existing controller redis-master.
Scaling up redis-master from 1 to 1, scaling down redis-master-v2 from 1 to 0 (keep 1 pods available, don‘t exceed 2 pods)
Scaling redis-master-v2 down to 0
Update succeeded. Deleting redis-master-v2
replicationcontroller "redis-master" rolling updated to "redis-master-v2"

[[email protected]_master php-redis]# kubectl get rc -o wide
NAME           DESIRED   CURRENT   READY     AGE       CONTAINER(S)   IMAGE(S)                                     SELECTOR
frontend       3         3         3         14h       frontend       docker.io/kubeguide/guestbook-php-frontend   name=frontend
redis-master   1         1         1         29m       master         docker.io/kubeguide/redis-master             name=redis-master

[[email protected]_master php-redis]# kubectl get pods
NAME                 READY     STATUS    RESTARTS   AGE
redis-master-cgbjd   1/1       Running   0          29m

原文地址:https://www.cnblogs.com/FRESHMANS/p/9330806.html

时间: 2024-10-01 04:18:13

kubernetes 实践之Pod的相关文章

Docker Kubernetes 创建管理 Pod

Docker Kubernetes 容器扩容与缩容 环境: 系统:Centos 7.4 x64 Docker版本:18.09.0 Kubernetes版本:v1.8 管理节点:192.168.1.79 工作节点:192.168.1.78 工作节点:192.168.1.77 管理节点:创建pod yaml文件 vim pod.yaml apiVersion: v1 kind: Pod metadata: name: pod-test labels: os: centos spec: contain

Kubernetes对象之Pod

系列目录 Pod是Kubernetes调度的最小单元.一个Pod可以包含一个或多个容器,因此它可以被看作是内部容器的逻辑宿主机.Pod的设计理念是为了支持多个容器在一个Pod中共享网络和文件系统 因此处于一个Pod中的多个容器共享以下资源: PID命名空间:Pod中不同的应用程序可以看到其他应用程序的进程ID. network命名空间:Pod中多个容器处于同一个网络命名空间,因此能够访问的IP和端口范围都是相同的.也可以通过localhost相互访问. IPC命名空间:Pod中的多个容器共享In

kubernetes实践指南(一)

一.Docker相关内容二.Kubernets简介三.kuadm安装k8s 一.Docker相关内容 1.Docker工具集 Docker三剑客:Compse.swarm.machine docker compose:适用于单机,容器编排定义 docker swarm:对所有Docker宿主机资源整合,集群管理 docker machine:初始化Docker环境,跨平台支持 mesos+marathonmesos:主机资源整合分配调度管理工具的框架marathon:基于Mesos的私有PaaS

kubernetes中的Pod简述与实践

Pod的概念详细的Pod解释可参考k8s官网,关于Pod的概念主要有以下几点:(1)Pod是kubernetes中你可以创建和部署的最小也是最简的单位.一个Pod代表着集群中运行的一个进程:(2)在Kubrenetes集群中Pod的使用方式:(3)Pod中如何管理多个容器 理解Pod上面已经说了"Pod是kubernetes中你可以创建和部署的最小也是最简的单位.一个Pod代表着集群中运行的一个进程."Pod中封装着应用的容器(有的情况下是好几个容器),存储.独立的网络IP,管理容器如

kubernetes 实践四:Pod详解

本篇是关于k8s的Pod,主要包括Pod和容器的使用.Pod的控制和调度管理.应用配置管理等内容. Pod的定义 Pod是k8s的核心概念一直,就名字一样,是k8s中一个逻辑概念.Pod是docekr容器的集合,每个Pod中至少有一个Pause容器和业务容器.和docker容器关注单个可用的资源不同,Pod更多在应用层的角度,将多个docker容器组合来实现作为一个应用,它是k8s中最小的资源单位. 结合docker本身容器的特性,Pod中所有容器都是共享资源,如磁盘.网络.CPU.内存等,同时

Kubernetes — 深入解析Pod对象:基本概念(一)

在上一篇文章中,我详细介绍了 Pod 这个 Kubernetes 项目中最重要的概念. 现在,你已经非常清楚:Pod,而不是容器,才是 Kubernetes 项目中的最小编排单位.将这个设计落实到 API 对象上,容器(Container)就成了 Pod 属性里的一个普通的字段.那么,一个很自然的问题就是:到底哪些属性属于 Pod 对象,而又有哪些属性属于 Container 呢? 要彻底理解这个问题,你就一定要牢记我在上一篇文章中提到的一个结论:Pod 扮演的是传统部署环境里“虚拟机”的角色.

Kubernetes对象之Pod详解(附安装部署方法)

首先介绍一下K8S是什么:(引用自K8S中文社区) Kubernetes是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署.自动扩缩容.维护等功能. 通过Kubernetes你可以: 快速部署应用 快速扩展应用 无缝对接新的应用功能 节省资源,优化硬件资源的使用 其实K8S能够做的事情有很多,而且操作简单,十分方便,下面先介绍如何安装,然后是对于pod详细介绍,如果你对docker还不怎么了解,可以先参考前面的文章学习一下! 环境介绍: CentOS 7.2 Kubernetes

Kubernetes 实践之 service

service是k8s最核心的概念.通过创建service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上去 service定义详解 ymal格式的service定义文件的完整内容如下 apiVersion: v1 #必须 kind: Service #必须 matadata: #必须,元数据 name: string #必须,service的名称 namespace: string #非必须,指定的namespace名称,与rc在同一个name

kubernetes 无法删除 pod 问题的解决

[摘要] kubernetes 可能会产生垃圾或者僵尸pod,在删除rc的时候,相应的pod没有被删除,手动删除pod后会自动重新创建,这时一般需要先删除掉相关联的resources,实际中还要具体情况具体分析. 在使用Helm部署gitlab的时候发现有垃圾的pod存在,一直删除不掉 # kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE gitlab-migrations.1-2km-4rwnm 1/1 Running