精华内容
下载资源
问答
  • 获取容器中的标准输出
    千次阅读
    2021-03-13 09:26:02

    日志系统要求:

    1.因开发项目要求,一个pod 内有多个日志路径,需要收集

    2.同时需要收集pod 容器的标准输出日志

    环境:

    本次环境es、kibana 均部署在k8s 集群外,在物理机部署,只需要log-pilot 指定es 地址

    具体步骤:

    创建 daemonset log-pilot

    kubectl get daemonsets.apps log-pilot -o yaml

    apiVersion: apps/v1

    kind: DaemonSet

    metadata:

    labels:

    k8s-app: log-pilot

    name: log-pilot

    namespace: default

    spec:

    selector:

    matchLabels:

    k8s-app: log-es

    template:

    metadata:

    labels:

    k8s-app: log-es

    spec:

    containers:

    - env:

    - name: NODE_NAME

    valueFrom:

    fieldRef:

    apiVersion: v1

    fieldPath: spec.nodeName

    - name: PILOT_LOG_PREFIX

    value: mytest #收集容器日志前缀标识,容器日志必须指定同一标识 mytest

    - name: FILEBEAT_OUTPUT

    value: elasticsearch #日志指定输出位置为 es

    - name: ELASTICSEARCH_HOST

    value: 10.16.0.178 # es 地址

    - name: ELASTICSEARCH_PORT

    value: "9200" # es 端口

    image: yzsjhl-evdc-node03.opi.com/tj/log-pilot:0.9.5-filebeatv01

    imagePullPolicy: IfNotPresent

    name: log-pilot

    resources:

    limits:

    memory: 200Mi

    requests:

    cpu: 100m

    memory: 200Mi

    securityContext:

    capabilities:

    add:

    - SYS_ADMIN

    terminationMessagePath: /dev/termination-log

    terminationMessagePolicy: File

    volumeMounts:

    - mountPath: /var/run/docker.sock

    name: sock

    - mountPath: /host

    name: root

    readOnly: true

    - mountPath: /var/lib/filebeat

    name: varlib

    - mountPath: /var/log/filebeat

    name: varlog

    dnsPolicy: ClusterFirst

    restartPolicy: Always

    schedulerName: default-scheduler

    securityContext: {}

    terminationGracePeriodSeconds: 30

    volumes:

    - hostPath:

    path: /var/run/docker.sock

    type: ""

    name: sock

    - hostPath:

    path: /

    type: ""

    name: root

    - hostPath:

    path: /var/lib/filebeat

    type: DirectoryOrCreate

    name: varlib

    - hostPath:

    path: /var/log/filebeat

    type: DirectoryOrCreate

    name: varlog

    updateStrategy:

    rollingUpdate:

    maxUnavailable: 1

    type: RollingUpdate

    创建应用容器deployments (java 项目),有三个日志路径需要收集

    $ kubectl get deployments.apps gateway-deploy -o yaml

    apiVersion: apps/v1

    kind: Deployment

    metadata:

    name: gateway-deploy

    namespace: default

    spec:

    replicas: 2

    selector:

    matchLabels:

    app: gateway

    release: stabel

    strategy:

    rollingUpdate:

    maxSurge: 25%

    maxUnavailable: 25%

    type: RollingUpdate

    template:

    metadata:

    creationTimestamp: null

    labels:

    app: gateway

    env: test

    release: stabel

    spec:

    containers:

    - env:

    - name: TZ

    value: Asia/Shanghai

    - name: mytest_logs_gatewaystdout # 容器的标准输出日志

    value: stdout

    - name: mytest_logs_gatewayaccesslogdir #第一个应用日志

    value: /data/logs/service-gateway/access/*.log

    - name: mytest_logs_gatewayauthlogdir #第二个应用日志

    value: /data/logs/service-gateway/auth/*.log

    - name: mytest_logs_gatewayrootlogdir #第三个应用日志

    value: /data/logs/service-gateway/root/*.log

    image: yzsjhl-evdc-node03.opi.com/renren-backend/gateway:20200519161529

    imagePullPolicy: IfNotPresent

    name: gateway

    ports:

    - containerPort: 8089

    name: http1

    protocol: TCP

    - containerPort: 20007

    name: http2

    protocol: TCP

    resources: {}

    terminationMessagePath: /dev/termination-log

    terminationMessagePolicy: File

    volumeMounts: # 每个日志 emptyDir都需要挂载在容器日志的指定位置

    - mountPath: /data/logs/service-gateway/access

    name: gatewayaccess-logs

    - mountPath: /data/logs/service-gateway/auth

    name: gatewayauth-logs

    - mountPath: /data/logs/service-gateway/root

    name: gatewayroot-logs

    dnsPolicy: ClusterFirst

    restartPolicy: Always

    schedulerName: default-scheduler

    securityContext: {}

    terminationGracePeriodSeconds: 30

    volumes:

    - emptyDir: {} # 每个日志路径都需要指定一个 emptyDir

    name: gatewayaccess-logs

    - emptyDir: {}

    name: gatewayauth-logs

    - emptyDir: {}

    name: gatewayroot-logs

    查看kibana,看是否收集到日志:

    更多相关内容
  • K8s系列之:在容器获取Pod信息Downward API一、环境变量方式:将Pod信息注入为环境变量二、环境变量方式:将容器资源信息注入为环境变量三、Volume挂载方式四、Downward API价值 每个Pod在成功创建出来以后,都会...

    每个Pod在成功创建出来以后,都会被系统分配唯一的名字、IP地址,并且处于某个Namespace中。在Pod容器内要获取Pod这些重要信息,可以使用Downward API。

    Downward API可以通过以下两种方式将Pod信息注入容器底部:

    • 环境变量。用于单个变量,可以将Pod信息和Container信息注入容器内部。
    • Volume挂载:将数组类信息生成为文件,挂载到容器内部。

    一、环境变量方式:将Pod信息注入为环境变量

    下例通过Downward API将Pod的IP、名称和所在Namespace注入容器的环境变量中,容器应用使用env命令将全部环境变量打印到标准输出中:

    dapi-test-pod.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod
    spec:
      containers:
     - name: test-container
        image: busybox
        command: ["/bin/sh","-c","env"]
        env:
          - name: MY_POD_NAME
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: MY_POD_NAMESPACE
            valueFrom:
              fieldRef:
                fieldPath: metadata.namespace
          - name: MY_POD_IP
            valueFrom:
              fieldRef:
                fieldPath: status.podIP
    restartPolicy: Never
    

    注意到上面valueFrom这种特殊的语法是Downward API的写法。目前Downward API提供了以下变量。

    • metadata.name:Pod的名称,当Pod通过RC生成时,其名称是RC随机产生的唯一名称。
    • status.podIP:Pod的IP地址,之所以叫作status.podIP而非metadata.IP,是因为IP属于状态数据,而非元数据。
    • metadata.namespace:Pod所在的Namespace。

    运行kubectl create命令创建Pod:

    kubectl create -f dapi-test-pod.yaml
    

    查看dapi-test-pod的日志:

    kubectl logs dapi-test-pod
    ......
    MY_POD_NAMESPACE=default
    MY_POD_IP=172.17.1.2
    MY_POD_NAME=dapi-test-pod
    

    从日志中可以看到Pod的IP、Name及Namespace等信息都被正确保存到了Pod的环境变量中。

    二、环境变量方式:将容器资源信息注入为环境变量

    下例通过Downward API将Container的资源请求和限制信息注入容器的环境变量中,容器应用使用printenv命令将设置的资源请求和资源限制环境变量打印到标准输出中:
    dapi-test-pod-container-vars.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod-container-vars
    spec:
      containers:
     - name: test-container
       image: busybox
       command: ["sh","-c"]
       args:
     - while true;do
          echo -en '\n';
          printenv MY_CPU_REQUEST MY_CPU_LIMIT;
          printenv MY_MEM_REQUEST MY_MEM_LIMIT;
          sleep 3600;
         done;
    	resources:
    	  requests:
    	    memory: "32Mi"
    	    cpu: "125m"
    	  limits:
    	    memory: "64Mi"
    	    cpu: "250m"
    	env:
    	  - name: MY_CPU_REQUEST
    	    valueFrom:
    	      resourceFieldRef:
    	        containerName: test-container
    	        resource: request.cpu
    	  - name: MY_CPU_LIMIT
    	    valueFrom:
    	      resourceFieldRef:
    	        containerName: test-container
    	        resource: limits.cpu
    	  - name: MY_MEM_REQUEST
    	    valueFrom:
    	      resourceFieldRef:
    	        containerName: test-container
    	        resource: request.memory
    	  - name: MY_MEM_LIMIT
    	  	valueFrom:
    	  	  resourceFieldRef:
    	  	    containerName: test-container
    	  	    resource: limits.memory
    restartPolicy: Never	
    

    注意valueFrom这种特殊的Downward API语法,目前resourceFieldRef可以将容器的资源请求和资源限制等配置设置为容器内部的环境变量。

    • request.cpu:容器的CPU请求值
    • limits.cpu:容器的CPU限制值
    • requests.memory:容器的内存请求值
    • limits.memory:容器的内存限制值
    kubectl create -f dapi-test-pod-container-vars.yaml
    kubectl get pods
    

    查看dapi-test-pod-container-vars的日志:

    kubectl logs dapi-test-pod-container-vars
    

    从日志中可以看到Container的requests.cpu、limits.cpu、requests.memory、limits.memory等信息被正确保存到了Pod的环境变量中。

    三、Volume挂载方式

    下例通过Downward API将Pod的Label、Annotation列表通过Volume挂载为容器内的一个文件,容器应用使用echo命令将文件内容打印到标准输出中:

    dapi-test-pod-volume.yaml

    apiVersion: v1
    kind: Pod
    metadata:
      name: dapi-test-pod-volume
      labels:
        zone: us-est-coast
        cluster: test-cluster1
        rack: rack-22
      annotations:
        build: two
        builder: john-doe
    spec:
      containers:
     - name: test-container
       image: busybox
       imagePullPolicy: Never
       command: ["sh","-c"]
       args:
     - whild true; do
          if [[ -e /etc/labels ]]; then
          	echo -en '\n\n'; cat /etc/labels; fi;
          if [[ -e /etc/annotations ]]; then
            echo -en '\n\n'; cat /etc/annotations; fi;
          sleep 3600;
        done;
      volumeMounts:
      	- name: podinfo
      	  mountPath: /etc
      	  readOnly: false
      volumes:
        - name: podinfo
          downwardAPI:
            items:
              - path: "labels"
                fieldRef:
                  fieldPath: metadata.labels
              - path: "annotations"
              	fieldRef:
              	  fieldPath: metadata.annotations
    

    注意volumes中downwardAPI的特殊语法,通过items的设置,将会以path的名称生成文件。

    • 将在容器内生成/etc/labels和/etc/annotations两个文件,/etc/labels中将包含metadata.labels的全部Label列表,/etc/annotations中将包含metadata.annotations的全部Label列表。

    运行kubectl create命令创建Pod

    kubectl create -f dapi-test-pod-volume.yaml
    
    kubectl get pods
    

    查看dapi-test-pod-volume的日志:

    kubectl logs dapi-test-pod-volume
    zone="us-est-coast"
    cluster="test-cluster1"
    rack="rack-22"
    
    build="two"
    builder="john-doe" 
    

    从日志中看到Pod的Label和Annotation信息都被保存到了容器内的/etc/labels和/etc/annotations文件中。

    四、Downward API价值

    • 在某些集群中,集群中的每个节点都需要将自身标识ID及进程绑定的IP地址等信息事先写入配置文件中,进程启动时读取这些信息,然后发不到某个类似服务注册中心的地方,以实现集群节点的自动发现功能。
    • 此时Downward API就可以派上用场了,具体做法是先编写一个预启动脚本或Init Container,通过环境变量或文件方式获取Pod自身的名称、IP地址等信息,然后写入主程序的配置文件中,最后启动主程序。
    展开全文
  • 将日志输出到Docker容器

    千次阅读 2021-01-14 03:59:22
    1.1 使用 Docker 容器日志我们可以利用 docker ...docker logs 会监控容器中操作系统的标准输出设备(STDOUT),一旦 STDOUT 有数据产生,就会将这些数据传输到另一个“设备”,该 Docker 的被称为“日志驱动(Loggin...

    1.1 使用 Docker 容器日志

    我们可以利用 docker logs 命令查看 Docker 容器内部应用程序运行时所产生的日志,可以免除首先进入 Docker 容器,再打开应用程序的日志文件的过程。docker logs 会监控容器中操作系统的标准输出设备(STDOUT),一旦 STDOUT 有数据产生,就会将这些数据传输到另一个“设备”中,该 Docker 的被称为“日志驱动(Logging Driver)”

    1.2 Docker 日志驱动

    例如,我们有一个容器实例 ID 为 “da6743d61e1a” ,随后我们使用 docker logs 命令,查看 da6743d61e1a 容器的日志docker logs -f da6743d61e1a

    此时,Docker 日志也在同步输出,输出的日志类似下面这样。.   ____          _            __ _ _

    /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \

    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \

    \\/  ___)| |_)| | | | | || (_| |  ) ) ) )

    '  |____| .__|_| |_|_| |_\__, | / / / /

    =========|_|==============|___/=/_/_/_/

    :: Spring Boot ::        (v1.5.3.RELEASE)

    2018-08-31 14:39:34.608  INFO 8 --- [           main] com.ctego.inventory.server.Server        : Starting Server on ctego-inventory-srv-55798d4965-lfdxn with PID 8 (/var/ctego/server.jar started by root in /)

    2018-08-31 14:39:34.696 DEBUG 8 --- [           main] com.ctego.inventory.server.Server        : Running with Spring Boot v1.5.3.RELEASE, Spring v4.3.8.RELEASE

    2018-08-31 14:39:34.697  INFO 8 --- [           main] com.ctego.inventory.server.Server        : No active profile set, falling back to default profiles: default

    2018-08-31 14:39:46.125  INFO 8 --- [           main] c.l.s.valid.DefaultValidConfig           : 开启参数校验

    2018-08-31 14:39:48.102  INFO 8 --- [           main] org.xnio                                 : XNIO version 3.3.6.Final

    2018-08-31 14:39:48.208  INFO 8 --- [           main] org.xnio.nio                             : XNIO NIO Implementation Version 3.3.6.Final

    2018-08-31 14:39:48.602  WARN 8 --- [           main] io.undertow.websockets.jsr               : UT026009: XNIO worker was not set on WebSocketDeploymentInfo, the default worker will be used

    2018-08-31 14:39:48.602  WARN 8 --- [           main] io.undertow.websockets.jsr               : UT026010: Buffer pool was not set on WebSocketDeploymentInfo, the default pool will be used

    2018-08-31 14:39:48.701  INFO 8 --- [           main] io.undertow.servlet                      : Initializing Spring embedded WebApplicationContext

    Docker 是怎样做到的呢?或者说,所谓的 Docker 日志驱动,到底做了些什么事情?

    我们使用 docker info 命令,可以看到 Docker 容器的相关信息,其中有一项 Logging Driver 的字段。docker info | grep 'Logging Driver'

    通过输入以上命令,将得到Docker 当前所设置的日志驱动类型:journaldLogging Driver: journald

    其实,Docker 已为我们提供了大量的日志驱动类型。none:容器不输出任何日志;

    json-file:容器输出的日志以 JSON 格式写入文件中(默认);

    syslog:容器输出的日志写入宿主机的 Syslog 中;

    journald:容器输出的日志写入宿主机的 Journald 中;

    gelf:容器输出到日志以 GELF(Graylog Extended Log Format)格式写入 Graylog中;

    fluentd:容器输出的日志写入宿主机的 Fluented 中;

    awslogs:容器输出的日志写入 Amazon CloudWatch Logs 中;

    splunk:容器输出的日志写入 splunk 中;

    etwlogs:容器输出的日志写入 ETW (Event Tracing for Windows);

    mats:容器输出的日志写入 NATS 服务中;

    我们可以在 docker run 命令中通过  --log-driver 参数来设置具体的 Docker 日志驱动,也可以通过 --log-opt 参数来指定对应日志驱动的相关选项。就拿 json-file 来说,其实可以这样启动 Docker 容器:docker run \

    -d \

    -p 80:80 \

    --log-driver json-file \

    --log-opt max-size=10m \

    --log-opt max-file=3 \

    --name nginx \

    nginx

    通过 --log-opt 参数为 json-file 日志驱动添加了两个选项,max-size=10m 表示  JSON 文件最大为 10MB(超过 10MB 就会自动生成新文件),max-file=3 表示 JSON 文件最多为3个(超过3个就会自动删除多余的旧文件)

    除了在启动 Docker 容器时,可指定日志驱动以外,还可以通过修改 Docker 配置文件来指定日志驱动。

    打开配置文件 /etc/sysconfig/docker,找到以下配置片段:OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false'

    if [ -z "${DOCKER_CERT_PATH}" ]; then

    DOCKER_CERT_PATH=/etc/docker

    fi

    可以看出,默认的日志驱动为 journald,把它修改为 syslog--log-driver=syslog

    然后重启 dockersystemctl restart docker本文中所使用的 docker 版本为 1.13.1

    新版本的docker中,已废弃/etc/sysconfig/docker这种配置方式,转而采用/etc/docker/daemon.json来配置

    详情请阅读 官方文档

    以上众多日志驱动类型中,较为常用 的是 Syslog,因为 Syslog 是 Linux 的日志系统,很多日志分析工具都可以从 Syslog 中获取日志,比如流行的 ELK(Elasticsearch、Logstash、Kibana)日志中心。Logstash 用于收集日志,Syslog 中写入的日志可转发到 Logstash 中,随后将日志存入 Elasticsearch 中,最后可通过 Kibana 来查询日志。

    接下来咱们的目标是将 Docker 容器中输出的日志写入 Syslog,那么后面需要做的就是将 Syslog 接入 ELK 了。

    1.3 Linux 日志系统:Syslog

    默认,Linux 操作系统已经安装了 Syslog 软件包,但它叫 Rsyslog。实际上,Rsyslog 是 Syslog 标准的一种实现,还有一种叫 Syslog-ng 的第三方实现。虽然 Syslog-ng 的功能较为强大,但我们还是选择使用 Rsyslog,因为操作系统已经预装了,我们无须单独安装,可以通过以下命令查看 Rsyslog 是否已安装。[root@uat-k8s-master1 ~]# rsyslogd -v

    rsyslogd 8.24.0, compiled with:

    PLATFORM:               x86_64-redhat-linux-gnu

    PLATFORM (lsb_release -d):

    FEATURE_REGEXP:             Yes

    GSSAPI Kerberos 5 support:      Yes

    FEATURE_DEBUG (debug build, slow code): No

    32bit Atomic operations supported:  Yes

    64bit Atomic operations supported:  Yes

    memory allocator:           system default

    Runtime Instrumentation (slow code):    No

    uuid support:               Yes

    Number of Bits in RainerScript integers: 64

    如果要开启 Rsyslog 服务,我们必须对 Rsyslog 进行配置,打开文件 vi /etc/rsyslog.conf

    在 rsyslog.conf 文件中有一段配置,我们需要手工去开启$ModLoad imtcp$InputTcpServerRun 514

    重启 Rsyslog 服务,否则配置无法生效systemctl restart rsyslog

    此时,我们可以查看本地是否对外开启了 514 端口[root@uat-k8s-master1 ~]# netstat -anpt | grep 514

    tcp        0      0 0.0.0.0:514             0.0.0.0:*               LISTEN      20681/rsyslogd

    tcp6       0      0 :::514

    作者:CPChen

    链接:https://www.jianshu.com/p/bf2eb121ac62

    展开全文
  • Docker容器基础介绍

    千次阅读 2020-12-23 21:58:29
    Docker是PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。Docker是通过内核虚拟化技术(namespace以及cgroups等)来提供容器的资源隔离与安全...

    Docker是PaaS 提供商 dotCloud 开源的一个基于 LXC 的高级容器引擎,源代码托管在 Github 上, 基于go语言并遵从Apache2.0协议开源。Docker是通过内核虚拟化技术(namespace以及cgroups等)来提供容器的资源隔离与安全保障。由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机( VM)额外的操作系统开销,提高资源利用率。

    Docker是使用Go语言编写的一个程序运行、测试、交付的开放平台,Docker被设计为能够使你快速地交付应用。在Docker中,你可以将你的程序分为不同的基础部分,对于每一个基础部分都可以当做一个应用程序来管理。Docker能够帮助你快速地测试、快速地编码、快速地交付,并且缩短你从编码到运行应用的周期。Docker使用轻量级的容器虚拟化平台,并且结合工作流和工具,来帮助你管理、部署你的应用程序。Docker在其核心,Docker实现了让几乎任何程序都可以在一个安全、隔离的容器中运行。安全和隔离可以使你可以同时在机器上运行多个容器。Docker容器轻量级的特性,意味着可以得到更多的硬件性能。

    Docker原理:建立-->传送-->运行

    通过Docker Hub或者自己的Docker仓库分享Docker镜像, 从Docker镜像创建Docker容器, 在容器里运行应用程序。

    Docker镜像是如何工作的?

    Docker镜像是Docker容器运行时的只读模板,每一个镜像由一系列的层(layers)组成;Docker使用UnionFS(联合文件系统)来将这些层联合到一二镜像中,UnionFS文件系统允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。

    正因为有了这些层(layers)的存在,Docker才会如此的轻量。当你改变了一个Docker镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。所以你不用重新发布整个镜像,只需要升级。层使得分发Docker镜像变得简单和快速。

    每个镜像都是从一个基础的镜像开始的,比如ubuntu,一个基础的Ubuntu镜像,或者是Centos,一个基础的Centos镜像。你可以使用你自己的镜像作为新镜像的基础,例如你有一个基础的安装了Nginx的镜像,你可以使用该镜像来建立你的Web应用程序镜像。(Docker通常从Docker Hub获取基础镜像)

    Docker镜像从这些基础的镜像创建,通过一种简单、具有描述性的步骤,我们称之为 指令(instructions)。每一个指令会在镜像中创建一个新的层,指令可以包含这些动作:

    ->  运行一个命令。

    ->  增加文件或者文件夹。

    ->  创建一个环境变量。

    ->  当运行容器的时候哪些程序会运行。

    这些指令存储在Dockerfile文件中。当你需要建立镜像的时候,Docker可以从Dockerfile中读取这些指令并且运行,然后返回一个最终的镜像。

    Docker仓库的用处?

    Docker仓库是Docker镜像的存储仓库。可以推送镜像到Docker仓库中,然后在Docker客户端,可以从Docker仓库中搜索和拉取镜像。

    Docker容器是如何工作的?

    一个Docker容器包含了一个操作系统、用户添加的文件和元数据(meta-data)。每个容器都是从镜像建立的,镜像告诉Docker容器内包含了什么,当容器启动时运行什么程序,还有许多配置数据。Docker镜像是只读的,当Docker运行一个从镜像建立的容器,它会在镜像顶部添加一个可读写的层,应用程序可以在这里运行。

    Docker容器运行时会做哪些事情?

    使用docker命令时,Docker客户端都告诉Docker守护进程运行一个容器。

    # docker run -i -t ubuntu /bin/bash

    可以来分析这个命令,Docker客户端使用docker命令来运行,run参数表明客户端要运行一个新的容器。

    Docker客户端要运行一个容器需要告诉Docker守护进程的最小参数信息是:

    ->  这个容器从哪个镜像创建,这里是ubuntu,基础的Ubuntu镜像。

    ->  在容器中要运行的命令,这里是/bin/bash,在容器中运行Bash shell。

    那么运行这个命令之后在底层发生了什么呢?按照顺序,Docker做了这些事情:

    ->  拉取ubuntu镜像:Docker检查ubuntu镜像是否存在,如果在本地没有该镜像,Docker会从Docker Hub下载。如果镜像已经存在,Docker会使用它来创建新的容器。

    ->  创建新的容器:当Docker有了这个镜像之后,Docker会用它来创建一个新的容器。

    ->  分配文件系统并且挂载一个可读写的层:容器会在这个文件系统中创建,并且一个可读写的层被添加到镜像中。

    ->  分配网络/桥接接口:创建一个允许容器与本地主机通信的网络接口。

    ->  设置一个IP地址:从池中寻找一个可用的IP地址并且服加到容器上。

    ->  运行你指定的程序:运行指定的程序。

    -> 捕获并且提供应用输出:连接并且记录标准输出、输入和错误让你可以看到你的程序是如何运行的。

    由此就可以拥有一个运行着的Docker容器了!从这里开始你可以管理你的容器,与应用交互,应用完成之后,可以停止或者删除你的容器。

    Docker与VM的区别:

    docker与Openstack的对比

    Docker用途:简单配置、代码流水线管理、开发效率、应用隔离、服务器整合、调试能力、多租户、快速部署

    Docker可以快速交付应用程序

    Docker可以为你的开发过程提供完美的帮助。Docker允许开发者在本地包含了应用程序和服务的容器进行开发,之后可以集成到连续的一体化和部署工作流中。举个例子,开发者们在本地编写代码并且使用Docker和同事分享其开发栈。当开发者们准备好了之后,他们可以将代码和开发栈推送到测试环境中,在该环境进行一切所需要的测试。从测试环境中,你可以将Docker镜像推送到服务器上进行部署。

    Docker可以让开发和拓展更加简单

    Docker的以容器为基础的平台允许高度可移植的工作。Docker容器可以在开发者机器上运行,也可以在实体或者虚拟机上运行,也可以在云平台上运行。Docker的可移植、轻量特性同样让动态地管理负载更加简单。你可以用Docker快速地增加应用规模或者关闭应用程序和服务。Docker的快速意味着变动几乎是实时的。

    Docker可以达到高密度和更多负载

    Docker轻巧快速,它提供了一个可行的、符合成本效益的替代基于虚拟机管理程序的虚拟机。这在高密度的环境下尤其有用。例如,构建你自己的云平台或者PaaS,在中小的部署环境下同样可以获取到更多的资源性能。

    Docker改变了什么?

    -> 面向产品:产品交付

    -> 面向开发:简化环境配置

    -> 面向测试:多版本测试

    -> 面向运维:环境一致性

    -> 面向架构:自动化扩容

    Docker组件:镜像(Image)、容器(Container)、仓库(Repository)

    Docker 架构:C/S架构

    -> Docker使用客户端-服务器(client-server)架构模式。

    -> Docker 客户端会与Docker守护进程进行通信。Docker 守护进程会处理复杂繁重的任务,例如建立、运行、发布你的 Docker 容器。

    -> Docker 客户端和守护进程可以运行在同一个系统上,当然也可以使用Docker客户端去连接一个远程的 Docker 守护进程。

    -> Docker 客户端和守护进程之间通过socket或者RESTful API进行通信。

    Docker守护进程

    如上图所示,Docker守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是通过 Docker 客户端间接和其通信。

    Docker 客户端

    Docker 客户端,实际上是 docker 的二进制程序,是主要的用户与 Docker 交互方式。它接收用户指令并且与背后的 Docker 守护进程通信,如此来回往复。

    Docker 内部

    要理解Docker内部构建,需要理解以下三种部件:

    Docker 镜像 - Docker Images

    Docker 仓库 - Docker Registry

    Docker 容器 - Docker Containers

    Docker镜像是Docker容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。Docker 使用 UnionFS 来将这些层联合到单独的镜像中。UnionFS 允许独立文件系统中的文件和文件夹(称之为分支)被透明覆盖,形成一个单独连贯的文件系统。正因为有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新 的层被添加或升级了。现在你不用重新发布整个镜像,只需要升级,层使得分发 Docker 镜像变得简单和快速。

    Docker仓库用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。Docker 仓库是 Docker 的分发部分。

    Docker容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。

    libcontainer

    Docker 从 0.9 版本开始使用 libcontainer 替代 lxc,libcontainer 和 Linux 系统的交互图如下:

    下面说下Docker容器的底层技术:Namesapce(资源隔离)和Cgroup(资源限制)

    命名空间   [Namespaces]

    =>   pid namespace:使用在进程隔离(Process ID)

    不同用户的进程就是通过pid namespace隔离开的,且不同 namespace 中可以有相同 PID。

    具有以下特征:

    -> 每个namespace中的pid是有自己的pid=1的进程(类似 /sbin/init 进程)

    -> 每个 namespace 中的进程只能影响自己的同一个 namespace 或子 namespace 中的进程

    -> 因为 /proc 包含正在运行的进程,因此在 container 中的 pseudo-filesystem 的 /proc 目录只能看到自己namespace 中的进程

    -> 因为 namespace 允许嵌套,父 namespace 可以影响子 namespace 的进程,所以子 namespace 的进程可以在父namespace中看到,但是具有不同的 pid

    =>   mnt namespace:使用在管理挂载点(Mount)

    类似 chroot,将一个进程放到一个特定的目录执行。mnt namespace 允许不同namespace的进程看到的文件结构不同,这样每个namespace 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个 namespace 中的 container 在 /proc/mounts 的信息只包含所在namespace的mount point。

    =>   net namespace:使用在进程网络接口(Networking)

    网络隔离是通过 net namespace 实现的, 每个 net namespace 有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个 container 的网络就能隔离开来。 docker 默认采用 veth 的方式将 container 中的虚拟网卡同 host 上的一个 docker bridge 连接在一起。

    =>   uts namespace:使用在隔离内核和版本标识 (Unix Timesharing System)

    UTS ("UNIX Time-sharing System") namespace 允许每个 container 拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 Host 上的一个进程。

    =>   ipc namespace:使用在管理进程间通信资源 (InterProcess Communication)

    container 中进程交互还是采用 Linux 常见的进程间交互方法 (interprocess communication - IPC), 包括常见的信号量、消息队列和共享内存。然而同 VM 不同,container 的进程间交互实际上还是 host 上具有相同 pid namespace 中的进程间交互,因此需要在IPC资源申请时加入 namespace 信息 - 每个 IPC 资源有一个唯一的 32bit ID。

    =>  user namespace:使用在管理空户空间

    每个 container 可以有不同的 user 和 group id, 也就是说可以以 container 内部的用户在 container 内部执行程序而非 Host 上的用户。

    有了以上6种namespace从进程、网络、IPC、文件系统、UTS 和用户角度的隔离,一个 container 就可以对外展现出一个独立计算机的能力,并且不同container从OS层面实现了隔离。然而不同 namespace 之间资源还是相互竞争的,仍然需要类似ulimit 来管理每个container所能使用的资源。

    资源配额 [cgroups]

    Docker还使用到了cgroups技术来管理群组。使应用隔离运行的关键是让它们只使用你想要的资源。这样可以确保在机器上运行的容器都是良民(good multi-tenant citizens)。群组控制允许Docker分享或者限制容器使用硬件资源。例如,限制指定的容器的内容使用。

    cgroups实现了对资源的配额和度量。 cgroups 的使用非常简单,提供类似文件的接口,在 /cgroup 目录下新建一个文件夹即可新建一个 group,在此文件夹中新建 task 文件,并将 pid 写入该文件,即可实现对该进程的资源控制。具体的资源配置选项可以在该文件夹中新建子 subsystem ,{子系统前缀}.{资源项} 是典型的配置方法, 如 memory.usageinbytes 就定义了该 group 在 subsystem memory 中的一个内存限制选项。另外,cgroups 中的 subsystem 可以随意组合,一个 subsystem 可以在不同的 group 中,也可以一个 group 包含多个 subsystem - 也就是说一个 subsystem。

    =>  memory

    内存相关的限制

    =>  cpu

    在 cgroup 中,并不能像硬件虚拟化方案一样能够定义 CPU 能力,但是能够定义 CPU 轮转的优先级,因此具有较高 CPU 优先级的进程会更可能得到 CPU 运算。 通过将参数写入 cpu.shares ,即可定义改 cgroup 的 CPU 优先级 - 这里是一个相对权重,而非绝对值

    =>  blkio

    block IO 相关的统计和限制,byte/operation 统计和限制 (IOPS 等),读写速度限制等,但是这里主要统计的都是同步 IO

    =>  devices

    设备权限限制

    Docker 联合文件系统

    联合文件系统(UnionFS)是用来操作创建层的,使它们轻巧快速。Docker使用UnionFS提供容器的构造块。Docker可以使用很多种类的UnionFS包括AUFS, btrfs, vfs, and DeviceMapper。

    Docker 容器格式

    Docker连接这些组建到一个包装中,称为一个 container format(容器格式)。默认的容器格式是libcontainer。Docker同样支持传统的Linux容器使用LXC。在未来,Docker也许会支持其它的容器格式,例如与BSD Jails 或 Solaris Zone集成。

    ======================== Docker环境的安装部署==========================

    环境准备(centos7)

    # yum install -y docker

    # systemctl start docker

    # systemctl enable docker

    镜像的查看(docker images信息结果包括:镜像仓库、标签、镜像ID、创建时间、镜像大小   )

    [root@linux-node2 ~]# docker images

    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

    docker.io/centos latest 60e65a8e4030 36 hours ago 196.6 MB

    docker.io/nginx latest 813e3731b203 9 days ago 133.8 MB

    docker.io/registry latest a8706c2bfd21 2 weeks ago 422.8 MB

    镜像的导出、导入和下载(可以将本机下载的镜像导出,然后将导出文件上传到别的机器上,在别的机器上进行镜像导入)

    [root@linux-node2 ~]# docker pull centos

    [root@linux-node2 ~]# docker save centos > /opt/centos.tar.gz

    将linux-node2的镜像导出文件上传到linux-node1机器上,然后在linux-node1机器上导入

    [root@linux-node1 ~]# docker load < /opt/centos.tar.gz

    镜像的删除(rmi后面可以跟多个id,用空格隔开)

    docker rmi container_id

    [root@linux-node2 ~]# docker rmi 813e3731b203

    Docker重命名镜像名称和TAG

    # docker tag IMAGEID(镜像id) REPOSITORY:TAG(仓库:标签)

    [root@docker-test2 ~]# docker images

    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

    93ec41b5ed04 About an hour ago 435.9 MB

    [root@docker-test2 ~]# docker tag 93ec41b5ed04 kevin/nginx:v1

    [root@docker-test2 ~]# docker images

    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

    kevin/nginx v1 93ec41b5ed04 About an hour ago 435.9 MB

    首次创建一个简单的容器

    [root@linux-node2 ~]# docker run centos /bin/echo "hehe"

    hehe

    查看容器状态

    可以使用docker ps只能看见存活的容器,docker ps -a 查看全部的容器,结果信息表示:

    容器ID、使用的镜像、执行的命令、创建的时间、状态、端口、名称(如果不指定,自动生成)

    [root@linux-node2 ~]# docker ps -a

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    daeb4d7f7aab centos "/bin/echo hehe" About a minute ago Exited (0) About a minute ago insane_einstein

    创建容器

    --name:指定容器名称

    -t :分配一个tty终端

    -i :容器的标准输保持打开的状态

    [root@linux-node2 ~]# docker run --name mydocker -t -i centos /bin/bash

    [root@94ab7a046f7c /]# ps aux

    USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

    root 1 0.0 0.1 11772 1872 ? Ss 03:42 0:00 /bin/bash

    root 14 0.0 0.0 35888 1472 ? R+ 03:43 0:00 ps aux

    这种方式创建自动进入容器,开启的容器只执行/bin/bash;

    在容器中查看主机名

    [root@94ab7a046f7c /]# hostname

    94ab7a046f7c

    [root@94ab7a046f7c /]# exit

    启动、停止容器

    # docker stop ID

    # docker start ID

    进入容器

    [root@linux-node2 ~]# docker attach 94ab7a046f7c

    [root@94ab7a046f7c /]#

    删除容器

    [root@linux-node2 ~]# docker rm ID/名称

    加-f 强制删除,包括正在运行中的容器

    映射

    随机映射 (端口的映射是系统自动分配的)

    [root@linux-node2 ~]# docker run -d -P nginx

    90316d97ee975b4e62e1927a9fb31f20703556b1a3ea07880d0c68dcb5bbd3bb

    [root@linux-node2 ~]# docker ps -l

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    90316d97ee97 nginx "nginx -g 'daemon off" 25 seconds ago Up 23 seconds 0.0.0.0:32769->80/tcp, 0.0.0.0:32768->443/tcp ecstatic_almeida

    指定映射 (如下,指定容器的80端口映射到主机的81端口上)

    [root@linux-node2 ~]# docker run -d -p 81:80 nginx

    0294a8f5b4fc81ba31383a8eb98ec62b136826eba92360c84afd87bf1bf819fc

    [root@linux-node2 ~]# docker ps

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    0294a8f5b4fc nginx "nginx -g 'daemon off" 11 seconds ago Up 10 seconds 443/tcp, 0.0.0.0:81->80/tcp admiring_ramanujan

    查看日志

    命令为"docker logs +ID"

    数据管理

    数据卷

    默认挂载目录

    创建一个数据卷,名称是volume-test1,挂载到data下默认挂载目录

    [root@linux-node2 ~]# docker run -it --name volume-test1 -v /data centos

    [root@1768d6414cfc /]# ls -l /data/

    total 0

    列出容器的所有信息,查看mounts模块

    [root@linux-node2 ~]# docker inspect 1768d6414cfc

    "Mounts": [

    {

    "Name": "55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167",

    "Source": "/var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data",

    "Destination": "/data",

    "Driver": "local",

    "Mode": "",

    "RW": true

    }

    ],

    查找挂载点并进入

    [root@linux-node2 ~]# ll /var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data

    总用量 0

    [root@linux-node2 ~]# cd /var/lib/docker/volumes/55c97df0276bb8879398b4e7286fc41f9872e9203267da7e23060e24ba06d167/_data

    创建一个cgt测试,并重新回到容器中查看

    [root@linux-node2 _data]# mkdir cgt

    去容器中查看

    [root@1768d6414cfc /]# ls -l /data/

    total 4

    drwxr-xr-x 2 root root 4096 Jan 4 14:04 cgt

    指定挂载目录。将容器的/opt映射到主机的/opt目录下(下面命令中前一个是主机路径,后一个是容器路径)

    [root@linux-node2 ~]# docker run -it --name volume-test1 -v /opt:/opt centos

    指定权限

    只需要在挂载后面加上权限即可。rw为读写,ro为只读

    [root@linux-node2 ~]# docker run -it --name volume-test1 -v /opt:/opt:rw centos

    挂载单个文件

    记录历史记录

    [root@linux-node2 ~]# docker run -it -v ~/.bash_history:/.bash_history centos

    数据卷容器

    让一个容器可以访问另一个容器的数据卷。启动两个容器

    启动nfs容器,挂在一个卷,使用-d直接在后台执行

    [root@linux-node2 ~]# docker run -d --name nfs -v /data centos

    209bc89b365ad6bc1eeae693ada01c04c2d08e9ee2b8816e624882944c116126

    启动test1容器,挂载到nfs的数据卷容器上,

    [root@linux-node2 ~]# docker run -it --name test1 --volumes-from nfs centos

    [root@5e399198d6a8 /]# ls /data/

    查看没内容

    找到nfs容器的挂载点(可以使用名称,不仅仅是ID)

    找到nfs容器的ID

    [root@linux-node2 opt]# docker ps -a

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    209bc89b365a centos "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago nfs

    找到nfs容器的挂载点

    [root@linux-node2 _data]# docker inspect nfs

    [root@linux-node2 opt]# cd /var/lib/docker/volumes/3938c9b1143d41340e148a4c7bc12d13b53966b15380c5b958a9e035897450d5/_data

    [root@linux-node2 _data]# touch cgt

    在test1上查看

    [root@5e399198d6a8 /]# ls /data/

    cgt

    注意:数据卷容器不论停止还是开启,不影响其他容器挂载使用

    如何制作镜像

    方式一:手动构建容器

    1)创建一个容器mynginx,使用centos镜像

    [root@linux-node2 ~]# docker run --name mynginx -it centos

    [root@f9c7dfb6f552 /]# rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

    [root@f9c7dfb6f552 /]# yum -y install nginx

    [root@f9c7dfb6f552 /]# exit

    exit

    2)基于mynginx容器做一个镜像mynginx:v1

    [root@linux-node2 ~]# docker ps -a

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    f9c7dfb6f552 centos "/bin/bash" 3 minutes ago Exited (0) 15 seconds ago mynginx

    基于mynginx这个容器做一个镜像

    [root@linux-node2 ~]# docker commit -m "my nginx" f9c7dfb6f552 cgt/mynginx:v1

    3f3adc859b77b2b47c3631229761bee6c7066f1c708bc01c5173c2ef5c0adce8

    提交镜像,同时打一个标签叫mynginx:v1,cgt相当于你向github上提交的用户名

    查看镜像

    [root@linux-node2 ~]# docker images

    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

    cgt/mynginx v1 3f3adc859b77 About a minute ago 326.4 MB

    3)基于mynginx:v1创建一个容器mynginxv1,目的是修改nginx不让其在后台运行

    [root@linux-node2 ~]# docker run -it --name nginxv1 cgt/mynginx:v1

    [root@ea64c5855006 /]# vi /etc/nginx/nginx.conf

    daemon off; # 不再后台运行

    [root@ea64c5855006 /]# exit

    exit

    [root@linux-node2 ~]# docker ps -a

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    ea64c5855006 cgt/mynginx:v1 "/bin/bash" 2 minutes ago Exited (0) 42 seconds ago nginxv1

    4)基于mynginxv1提交mynginxv2版本

    重新提交V2版本

    [root@linux-node2 ~]# docker commit -m "my nginx" ea64c5855006 cgt/mynginx:v2

    a480cdf9055ec4e640c65df6404c6ba42903ea77198a26cec75eef0e4965fe67

    查看V2镜像

    [root@linux-node2 ~]# docker images

    REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

    cgt/mynginx v2 a480cdf9055e 25 seconds ago

    5)基于mynginxv2镜像,创建mynginxv2容器

    启动容器,-d后台运行,-p指定端口 在后面是镜像,最后是命令(因为是yum安装的,可以直接写nginx,如果不是yum,那要写绝对路径)

    [root@linux-node2 ~]# docker run -d -p 82:80 cgt/mynginx:v2 nginx

    4eaf8a19034a673100f9355504628fad45e6ecbab91615afd6cb4e7a18b82171

    [root@linux-node2 ~]# docker ps

    CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

    4eaf8a19034a cgt/mynginx:v2 "nginx" 15 seconds ago Up 14 seconds 0.0.0.0:82->80/tcp elegant_leakey

    可以在浏览器访问82端口

    方式二:Dockerfile

    1)Dockerfile包含的信息

    -  基础镜像信息

    -  维护者信息

    -  镜像操作指令

    -  容器启动时执行指令

    2)文件的编写

    [root@linux-node2 ~]# mkdir /opt/dockerfile/nginx/ -p

    [root@linux-node2 ~]# cd /opt/dockerfile/nginx/

    将index.html上传到此处

    [root@linux-node2 nginx]# vim Dockerfile

    # This is docker file

    # version v1

    # Author wangshibo

    # Base image(基础镜像)

    FROM centos

    # Maintainer(维护者信息)

    MAINTAINER wangshibo 2134728394@qq.com

    # Commands(执行命令)

    RUN rpm -ivh http://mirrors.aliyun.com/epel/epel-release-latest-7.noarch.rpm

    RUN yum -y install nginx

    # Add(添加文件)

    ADD index.html /usr/share/nginx/html/index.html # index.html是自己编写的文件,放在后面的目录中,因为yum安装后Documentroot是在这里

    RUN echo "daemon off;" >>/etc/nginx/nginx.conf

    EXPOSE 80 # 对外的端口

    CMD ['nginx'] # 执行的命令

    3)构建容器,并运行。 建立newnginx容器,-t:标签,执行/opt/dockerfile/nginx/下面的默认的Dockerfile文件

    [root@linux-node2 nginx]# docker build -t cgt/mynginx:v3 /opt/dockerfile/nginx/

    [root@linux-node2 nginx]# docker run -d -p 83:80 cgt/mynginx:v3

    Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。当你真正投入容器Docker的怀抱,不但可以发现它能解决很多问题,而且还具有众多的优点:

    ->它是不可变的-操作系统,库版本,配置,文件夹和应用都是一样的。您可以使用通过相同QA测试的镜像,使产品具有相同的表现。

    ->它是轻量级的-容器的内存占用非常小。不需要几百几千MB,它只要对主进程分配内存再加上几十MB。

    -> 它很快速-启动一个容器与启动一个单进程一样快。不需要几分钟,您可以在几秒钟内启动一个全新的容器。

    许多用户依然像对待典型的虚拟机那样对待容器,似乎都忘记了除了与虚拟机相似的部分,容器还有一个很大的优点:它是一次性的。这个"特性"本身促使用户改变他们关于使用和管理容器的习惯;下面将会说明下在容器中不应该做这些事,以确保最大地发挥容器的作用。

    ->不要在容器中存储数据 – 容器可能被停止,销毁,或替换。一个运行在容器中的程序版本1.0,应该很容易被1.1的版本替换且不影响或损失数据。有鉴于此,如果你需要存储数据,请存在卷中,并且注意如果两个容器在同一个卷上写数据会导致崩溃。确保你的应用被设计成在共享数据存储上写入。

    ->不要将你的应用发布两份 – 一些人将容器视为虚拟机。他们中的大多数倾向于认为他们应该在现有的运行容器里发布自己的应用。在开发阶段这样是对的,此时你需要不断地部署与调试;但对于质量保证与生产中的一个连续部署的管道,你的应用本该成为镜像的一部分。记住:容器应该保持不变。

    ->不要创建超大镜像 – 一个超大镜像只会难以分发。确保你仅有运行你应用/进程的必需的文件和库。不要安装不必要的包或在创建中运行更新(yum更新)。

    ->不要使用单层镜像 – 要对分层文件系统有更合理的使用,始终为你的操作系统创建你自己的基础镜像层,另外一层为安全和用户定义,一层为库的安装,一层为配置,最后一层为应用。这将易于重建和管理一个镜像,也易于分发。

    ->不要为运行中的容器创建镜像 – 换言之,不要使用"docker commit"命令来创建镜像。这种创建镜像的方法是不可重现的也不能版本化,应该彻底避免。始终使用Dockerfile或任何其他的可完全重现的S2I(源至镜像)方法。

    ->不要只使用"最新"标签 – 最新标签就像Maven用户的"快照"。标签是被鼓励使用的,尤其是当你有一个分层的文件系统。你总不希望当你2个月之后创建镜像时,惊讶地发现你的应用无法运行,因为最顶的分层被非向后兼容的新版本替换,或者创建缓存中有一个错误的"最新"版本。在生产中部署容器时应避免使用最新。

    ->不要在单一容器中运行超过一个进程-容器能完美地运行单个进程(http守护进程,应用服务器,数据库),但如果运行多个进程,管理、获取日志、独立更新都会遇到麻烦。

    ->不要在镜像中存储凭据。使用环境变量 –不要将镜像中的任何用户名/密码写死。使用环境变量来从容器外部获取此信息。

    ->使用非root用户运行进程 – "docker容器默认以root运行。(…)随着docker的成熟,更多的安全默认选项变得可用。现如今,请求root对于其他人是危险的,可能无法在所有环境中可用。你的镜像应该使用USER指令来指令容器的一个非root用户来运行。"

    ->不要依赖IP地址 – 每个容器都有自己的内部IP地址,如果你启动并停止它地址可能会变化。如果你的应用或微服务需要与其他容器通讯,使用任何命名与(或者)环境变量来从一个容器传递合适信息到另一个。

    展开全文
  • 【云原生 | 05】Docker中容器的创建与启停

    千次阅读 多人点赞 2022-06-04 20:19:18
    首先Docker会检查本地是否存在基础镜像,如果本地还没有该镜像的话,那么Docker就会连接官方维护的Docker Hub Registry,查看Docker Hub是否有该镜像。Docker一旦找到该镜像,就会下载该镜像并将其保存到本地宿...
  • k8s已经成为当今容器化的标准,人们在享受容器带来的高效与便利的同时,也遇到一些烦恼:客户端和容器服务器之间可能存在多种不同形式的代理服务器,那容器中如何获取到客户端真实的源ip呢?下面我们就几种场景类型...
  • C++标准库-顺序容器

    千次阅读 2020-06-30 03:23:09
    标准的三种顺序容器3.容器构造方法二、容器的选择三、容器的操作1.顺序容器中的类型别名2.迭代器3.容器内的修改 一、 顺序容器概述 1.定义 容器就是特定类型对象的集合。顺序容器为程序员提供了控制元素存储和...
  • 获取Kubernetes容器上下文环境

    千次阅读 2019-01-02 17:33:41
     下面我们将主要介绍运行在Kubernetes集群容器所能够感知到的上下文环境,以及容器是如何获知这些信息的。  首先,Kubernetes提供了一个能够让容器感知到集群正在发生的事情的方法:环境变量。作为容器环境...
  • pdc:项目发现容器

    2021-03-19 05:20:48
    subfinder -silent | nuclei -t vulnerabilities/ echo "target.com" | subfinder -silent | dnsx -silent | naabu -silent | httpx -silent | nuclei -t cves/或使用一个不附加容器的命令来获取标准输出: docker ...
  • Java输入输出

    千次阅读 2021-02-12 21:28:28
    1什么是IOJavaI/O操作主要是指使用Java进行输入,输出操作。Java所有的I/O机制都是基于数据流进行输入输出,这些数据流表示了字符或者字节数据的流动序列。Java的I/O流提供了读写数据的标准方法。任何Java表示...
  • golang执行命令实时输出

    千次阅读 2021-06-20 21:53:35
    执行命令时,保证实时得到执行的日志,可以以通过下面的代码 实现 package utils import ( "fmt" ...func RunCommand(name string, ...// 命令的错误输出和标准输出都连接到同一个管道 stdout, err := cmd.Stdo..
  • 深入理解Java容器

    万次阅读 多人点赞 2016-07-27 17:25:40
    1、容器的概念 在Java当中,如果有一个类专门用来存放其它类的对象,这个类就叫做容器,或者就叫做集合,集合就是将...1、容器不是数组,不能通过下标的方式访问容器中的元素 2、数组的所有功能通过Arraylist容器
  • ISula 容器学习历程

    千次阅读 2021-12-29 14:29:33
    用法 isula stats [OPTIONS] [CONTAINER...] 示例 显示资源使用的统计信息 # isula stats --no-stream e9b998d05644 (容器ID部分首部) 3.16 获取容器日志 isula logs用于获取容器的日志。仅支持runtime类型为lcr...
  • 1.安装Docker yum install -y docker-io执行报错:[root@server1 ~]# yum install -y docker-io Loaded plugins: fastestmirror Determining fastest mirrors * base: mirrors.btte.net * extras: mirrors.btte.net...
  • Python有关网页操作的标准库有很多 这次使用两个流行的BeautifulSoup库和HTMLSession库的方法,在你需要在自己的程序插入指定网页的指定容器的内容时,可以插入下面的内容,因为你需要的信息可能是一直在变动的...
  • Kubernets:容器日志收集方案

    千次阅读 2020-03-14 13:46:35
    日志的形式变得更加复杂,不仅有物理机/虚拟机上的日志,还有容器标准输出容器内的文件、容器事件、Kubernetes 事件等等信息需要采集; 环境的动态性变强,在 Kubernetes ,机器的宕机、下线、上...
  • 【云原生】三、详细易懂的Docker 容器管理

    千次阅读 多人点赞 2022-06-08 20:43:27
    ;容器是 Docker 的一个基本概念,每个容器中都运行一个应用并为该应用提供完整的运行环境。 本文将详细学习 Docker 容器的创建,运行管理操作。
  • docker logs : 获取容器的日志

    千次阅读 2018-09-20 10:34:00
    2019独角兽企业重金招聘Python工程师标准>>> ...
  • 导读:近年来,越来越多的同学咨询如何为 Kubernetes 构建一个日志系统,或者是来求助在此过程遇到一系列问题如何解决,授人以鱼不如授人以渔,于是作者想把这些年积累的经验以文章的形式发出来,让看到文章的同学...
  • 操作Docker容器(1)创建容器

    千次阅读 2021-09-24 21:45:14
    操作Docker容器(1) 创建容器 ​ 从现在开始,你会一点一点的慢慢忘掉臃肿的虚拟机,对容器的操作就像直接操作应用一样简单和快速。 ​ 本节主要讲解Docker容器的create,start,run,wait,和logs子命令。 1.新建...
  • 在 Docker 容器中运行应用程序

    千次阅读 2017-11-01 10:49:00
    案例说明 运行 3 个容器,实现对网站的监控...容器mailer: 该容器中运行一个 mailer 程序,运行于后台,当接收到事件后会向管理员发送邮件。 容器agent: 该容器运行一个 watcher 程序,以交互模式运行,用于不断地监...
  • 为了能够适应容器云平台的管理模式和管理理念,应用系统需要完成容器化的改造过程。对于新开发的应用,建议直接基于微服务架构进行容器化的应用开发;对于已经运行多年的传统应用系统,也应该逐步将其改造成能够部署...
  • 【云原生】Docker容器详细讲解

    万次阅读 多人点赞 2022-07-19 19:15:51
    本文是对 Docker 容器的详细讲解,讲解了如何启动容器、进入容器,以及操作容器的命令。
  • docker(5):容器

    千次阅读 2021-04-27 20:17:07
    启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。 因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。 1.1 新建并启动 所需要...
  • OpenCV-获取图像直线上的数据

    万次阅读 多人点赞 2021-11-03 08:29:34
    OpenCV&C++代码实现获取图像直线上的数据
  • CPU使用率 CPU使用有点麻烦,最终的命令是: top -n1 | awk '/Cpu\(s\):/ {print $2}' 我们一一拆解,首先是top命令,这个是获取系统信息的: 加上-n1代表取消交互模式,只获取一次输出刷新。配合awk实现字段截取。...
  • 头文件主目录include头文件目录总共有32个.h头文件。其中主目录下有13个,asm子目录有4个,linux子目录有10个,sys子目录有5个。这些头文件各自的功能如下,具体的作用和所包含的信息请参见第14章。:a.out...
  • C++ 标准模板库 STL 关联容器

    千次阅读 2021-08-29 17:07:55
    C++ 标准模板库 STL 关联容器 容器 数据结构 时间复杂度 顺序性 重复性 set 红黑树 插入、删除、查找 O(log2n) 有序 不可重复 multiset 红黑树 插入、删除、查找 O(log2n) 有序 可重复 map 红黑树 插入...
  • 1.0 #docker exec -it f1 /bin/bash 2 docker logs实时输出脚本打印的内容 2.1 分析python命令的-u参数 #python -u xx.py python标准错误(std.err)和标准输出(std.out)的输出规则: 标准输出默认需要缓存后再...
  • 【云原生 | 01】docker容器引擎

    千次阅读 多人点赞 2022-05-27 20:21:22
    容器技术显然不是什么新概念,最早的容器技术可以追溯到 1979 年诞生的 chroot 技术 ,容器技术又称为容器虚拟化,这是虚拟化技术的一种 ,目前虚拟化技术主要有硬件虚拟化、半虚拟化和操作系统虚拟化等 。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 98,493
精华内容 39,397
关键字:

获取容器中的标准输出

友情链接: therr-oource.rar