一、docker技术
基于LXC技术之上构建的container容器引擎;
KVM:基于硬件虚拟化技术;
docker:内核虚拟化技术;
容器技术是一个轻量级的虚拟化技术,利用该技术能够将应用打包发布到不同的容器化服务器上运行;
每一个容器就是一个进程;
docker:单进程、不建议启动SSH;
docker应用场景:
简化配置 代码流水线管理:可以使用saltstack替换; 开发效率: 应用隔离: 服务器整合: debug调试的能力: 多租户: 快速部署: 总之一句话,一切看义务;
目前市场上使用docker的原因:
技术储备 无技术栈和技术债 跟上节奏、提升自身技术 符合当前业务需求 业务要求快
二、docker镜像和容器
docker的应用
面向产品:产品交付 面向开发:简化环境配置 面向测试:多版本测试 面向运维:环境一致性 面向架构:自动化扩容
docker镜像的导入和导出
docker save centos >/tmp/centos.tar.gz 导出镜像 [root@linux-node1 ~]# docker load < /tmp/centos.tar.gz 导入镜像 Loaded image: centos:latest
删除镜像
docker rmi c54a2cc56cbb #注意:如果镜像运行着容器,不能被删除,如果非要删除,使用-f参数强制删除
运行docker容器
[root@linux-node1 ~]# docker run centos /bin/echo "hehe"
查看帮助
[root@linux-node1 ~]# docker run --help #查看帮助 Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...] Run a command in a new container Options: --add-host value Add a custom host-to-IP mapping (host:ip) (default []) -a, --attach value Attach to STDIN, STDOUT or STDERR (default []) --blkio-weight value Block IO (relative weight), between 10 and 1000 --blkio-weight-device value Block IO weight (relative device weight) (default []) --cap-add value Add Linux capabilities (default []) --cap-drop value Drop Linux capabilities (default []) --cgroup-parent string Optional parent cgroup for the container --cidfile string Write the container ID to the file --cpu-percent int CPU percent (Windows only) --cpu-period int Limit CPU CFS (Completely Fair Scheduler) period --cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota -c, --cpu-shares int CPU shares (relative weight) --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-mems string MEMs in which to allow execution (0-3, 0,1) -d, --detach Run container in background and print container ID --detach-keys string Override the key sequence for detaching a container --device value Add a host device to the container (default []) --device-read-bps value Limit read rate (bytes per second) from a device (default []) --device-read-iops value Limit read rate (IO per second) from a device (default []) --device-write-bps value Limit write rate (bytes per second) to a device (default []) --device-write-iops value Limit write rate (IO per second) to a device (default []) --disable-content-trust Skip image verification (default true) --dns value Set custom DNS servers (default []) --dns-opt value Set DNS options (default []) --dns-search value Set custom DNS search domains (default []) --entrypoint string Overwrite the default ENTRYPOINT of the image -e, --env value Set environment variables (default []) --env-file value Read in a file of environment variables (default []) --expose value Expose a port or a range of ports (default []) --group-add value Add additional groups to join (default []) --health-cmd string Command to run to check health --health-interval duration Time between running the check --health-retries int Consecutive failures needed to report unhealthy --health-timeout duration Maximum time to allow one check to run --help Print usage -h, --hostname string Container host name -i, --interactive Keep STDIN open even if not attached --io-maxbandwidth string Maximum IO bandwidth limit for the system drive (Windows only) --io-maxiops uint Maximum IOps limit for the system drive (Windows only) --ip string Container IPv4 address (e.g. 172.30.100.104) --ip6 string Container IPv6 address (e.g. 2001:db8::33) --ipc string IPC namespace to use --isolation string Container isolation technology --kernel-memory string Kernel memory limit -l, --label value Set meta data on a container (default []) --label-file value Read in a line delimited file of labels (default []) --link value Add link to another container (default []) --link-local-ip value Container IPv4/IPv6 link-local addresses (default []) --log-driver string Logging driver for the container --log-opt value Log driver options (default []) --mac-address string Container MAC address (e.g. 92:d0:c6:0a:29:33) -m, --memory string Memory limit --memory-reservation string Memory soft limit --memory-swap string Swap limit equal to memory plus swap: '-1' to enable unlimited swap --memory-swappiness int Tune container memory swappiness (0 to 100) (default -1) --name string Assign a name to the container --network string Connect a container to a network (default "default") --network-alias value Add network-scoped alias for the container (default []) --no-healthcheck Disable any container-specified HEALTHCHECK --oom-kill-disable Disable OOM Killer --oom-score-adj int Tune host's OOM preferences (-1000 to 1000) --pid string PID namespace to use --pids-limit int Tune container pids limit (set -1 for unlimited) --privileged Give extended privileges to this container -p, --publish value Publish a container's port(s) to the host (default []) -P, --publish-all Publish all exposed ports to random ports --read-only Mount the container's root filesystem as read only --restart string Restart policy to apply when a container exits (default "no") --rm Automatically remove the container when it exits --runtime string Runtime to use for this container --security-opt value Security Options (default []) --shm-size string Size of /dev/shm, default value is 64MB --sig-proxy Proxy received signals to the process (default true) --stop-signal string Signal to stop a container, SIGTERM by default (default "SIGTERM") --storage-opt value Storage driver options for the container (default []) --sysctl value Sysctl options (default map[]) --tmpfs value Mount a tmpfs directory (default []) -t, --tty Allocate a pseudo-TTY --ulimit value Ulimit options (default []) -u, --user string Username or UID (format: <name|uid>[:<group|gid>]) --userns string User namespace to use --uts string UTS namespace to use -v, --volume value Bind mount a volume (default []) --volume-driver string Optional volume driver for the container --volumes-from value Mount volumes from the specified container(s) (default []) -w, --workdir string Working directory inside the container
运行一个docker
docker run --name mydocker -it centos /bin/bash
容器的主机名和容器的ID一致
[root@e1df9c83c21e ~]# hostname e1df9c83c21e [root@linux-node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e1df9c83c21e centos "/bin/bash" 2 minutes ago Up 59 seconds mydocker
使用docker run启动的容器,如果直接敲exit退出的话,就会直接停止掉(因为退出了那个bash),说明容器启动的时候,会指定一个进程,如果进程退出了,容器的生命周期就结束了也就是说,容器适合于单进程的情况;
启动创建的容器
[root@linux-node1 ~]# docker start mydocker mydocker
进入docker容器
方式a、使用attach [root@linux-node1 ~]# docker attach mydocker #attach进入docker,操作是同步的(打开两个窗口,显示操作同步,类似于vnc) [root@e1df9c83c21e /]# ll total 44 -rw-r--r--. 1 root root 18307 Nov 2 12:47 anaconda-post.log 方式b、使用nsenter [root@linux-node1 ~]# docker inspect --format "{{.State.Pid}}" mydocker #获取容器的Pid 11450 [root@linux-node1 ~]# nsenter -t 11450 -u -i -n -p [root@e1df9c83c21e ~]# 方式c、docker exec
进入容器的脚本
[root@linux-node1 ~]# cat ns.sh #使用脚本进入 #!/bin/sh PID=$(docker inspect --format "{{.State.Pid}}" $1) nsenter -t $PID -u -i -n -p
删除容器
[root@linux-node1 ~]# docker rm d20efe3fd38c d20efe3fd38c [root@linux-node1 ~]# docker rm -f 950ee143ab44 #-f参数可以删除正在运行的容器 950ee143ab44 [root@linux-node1 ~]# docker run --rm centos /bin/echo "hehe" #--rm参数表示在容器结束的时候自动删除,做实验的时候非常有用 hehe [root@linux-node1 ~]# docker ps -a -q #列出容器的ID e1df9c83c21e 4dc517e386be 0b86ca4c3702 1d49801a38d2 79356c74167d d75ec8677436 6ff4c7f458c6 da7afbb2980c cfd88cdeb001 cc98100c179c 110b89322bfb fcce9f38f6ce 3043794c3063 de0e9def8324 a550736ee4bd 4544cec722fc 96b516eb6d2d 3dac4ab3b0e0 [root@linux-node1 ~]# docker kill $(docker ps -q ) #杀死所有运行着的容器 e1df9c83c21e
三、docker的网络和存储
docker网络:
[root@linux-node1 ~]# docker run -d -P centos #-P创建时分配随机端口,-d表示后台运行 docker run --name mynginx -p 81:80 -it charlesedu/nginx:v1 #-p指定宿主机的端口和容器的端口 [root@linux-node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 9a66625c4b29 charlesedu/nginx:v1 "bash" 9 minutes ago Up 6 minutes 0.0.0.0:81->80/tcp mynginx
docker存储分为两种方式:
数据卷:
[root@linux-node1 ~]# docker run -it --name volume-test1 -v /data centos #启动容器,创建逻辑卷 /data,/data为容器中的目录 [root@linux-node1 ~]# docker inspect volume-test1 "Mounts": [ { "Name": "e40158fd2d3a6670c53d9e4c1f99257a002fdc1429d32b69a3dddf5884e1310b", "Source": "/var/lib/docker/volumes/e40158fd2d3a6670c53d9e4c1f99257a002fdc1429d32b69a3dddf5884e1310b/_data", #宿主机上挂载的目录 "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], [root@linux-node1 ~]# docker run -it -v ~/.bash_history:/.bash_history centos #启动容器,挂载文件.bash_history,可以记录历史命令
数据卷容器:(让一个容器访问另外一个容器的卷):
[root@linux-node1 ~]# docker run -d --name nfs -v /data centos #创建逻辑卷容器 [root@linux-node1 ~]# docker run -it --name test1 --volumes-from nfs centos #使用--volumes-form参数; [root@linux-node1 _data]# pwd #在nfs容器的挂载目录下创建文件 /var/lib/docker/volumes/3ca1723cce6d945586dc36803196d82840b89ed4b94343717ea5534834c9e22f/_data [root@linux-node1 _data]# ls helo [root@linux-node1 ~]# docker exec -it test1 bash [root@dcb986c5ec0a /]# cd /data/ #在test1容器下查看 [root@dcb986c5ec0a data]# ls helo
四、手动构建镜像
[root@linux-node1 ~]# 将容器构建为镜像 [root@linux-node1 ~]# docker commit -m "my nginx" nginx charlesedu/nginx:v1 #-m表示注释 [root@linux-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE charlesedu/nginx v1 aa4b7c63f112 About a minute ago 231.9 MB jumpserver latest 0b5196012b2d 9 weeks ago 146.6 MB centos latest 0584b3d2cf6d 3 months ago 196.5 MB alpine latest baa5d63471ea 3 months ago 4.799 MB ubuntu latest c73a085dc378 4 months ago 127 MB d20efe3fd38ccontainer-backup latest f8daa3270b6f 4 months ago 185 MB django latest a714d649863b 4 months ago 437.4 MB haproxy latest 65599e2ea3f2 5 months ago 139.1 MB redis latest 0d1cbfaa41da 5 months ago 185 MB ubuntu <none> bd3d4369aebc 5 months ago 126.6 MB [root@linux-node1 ~]# docker run -it --name nginxv1 charlesedu/nginx:v1 #使用提交的镜像创建容器 [root@41182d1d3cd9 /]#
五、Dockerfile构建镜像
FROM:基础镜像 MAINTAINER:维护者信息 RUN:把命令前面加上RUN ADD:COPY文件,向其中增加文件 WORKDIR:当前工作目录 VOLUME:目录挂载 EXPOSE:端口 RUN:进行要一直运行下去
[root@linux-node1 ~]# cat /opt/dockerfile/nginx/Dockerfile #This docker file #VERSION 1 #Author: Charles Chang #Base image FROM alyuan/centos6.5 #Maintainer MAINTAINER charles.chang qq_c123@163.com #Commands RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo RUN yum install -y nginx ADD index.html /usr/share/nginx/html/index.html RUN echo "daemon off;" >>/etc/nginx/nginx.conf EXPOSE 80 CMD ["nginx"]
使用dockerfile创建镜像
[root@linux-node1 ~]# docker build -t charlesedu/mynginx:v3 /opt/dockerfile/nginx/ Sending build context to Docker daemon 3.072 kB Step 1 : FROM alyuan/centos6.5 ---> 7fa31f3610cc Step 2 : MAINTAINER charles.chang qq_c123@163.com ---> Using cache ---> f79af4d02969 Step 3 : RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo ---> Using cache ---> e9b4689e79cb Step 4 : RUN yum install -y nginx ---> Using cache ---> a9a732c30b42 Step 5 : ADD index.html /usr/share/nginx/html/index.html ---> Using cache ---> f174ee46b797 Step 6 : RUN echo "daemon off;" >>/etc/nginx/nginx.conf ---> Using cache ---> 3a416b694140 Step 7 : EXPOSE 80 ---> Using cache ---> 669257ea20b9 Step 8 : CMD nginx ---> Running in acfca1c40c4e ---> 815554caea75 Removing intermediate container acfca1c40c4e Successfully built 815554caea75
注意:还有docker创建镜像,index.html需要和Dockerfile文件放在同一个目录下;如果创建的过程中断,下次不会从新开始;
CMD:表示最后需要执行的命令
[root@linux-node1 ~]# docker run --name mynginxtest -d -P charlesedu/mynginx:v3 #使用创建的dockerfile镜像创建容器 [root@linux-node1 nginx]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b2fbf7e046e2 charlesedu/mynginx:v3 "nginx" 54 seconds ago Up 49 seconds 0.0.0.0:10001->80/tcp mynginxtest
六、创建私有仓库
docker的三大理论:构建 运输 运行
类比:
DockerHub -->github
docker registry --> gitlab
启动registry
docker run -it -d -h docker-registry -v /data1/docker_volume/docker-registry:/var/lib/registry -v /data1/docker_volume/resolv.conf:/etc/resolv.conf:ro --cap-add SYS_PTRACE --net=none --restart=always --name docker-registry_172.16.22.18 2ef0b188834f
如何将镜像pull到私有的registry上?
[root@linux-node2 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry latest d1e32b95d8e8 2 weeks ago 33.17 MB jumpserver latest 0b5196012b2d 10 weeks ago 146.6 MB [root@linux-node2 ~]# docker tag jumpserver:latest 192.168.74.21:5000/charlesedu/myjumperver:latest #在pull之前,需要对镜像打tag [root@linux-node2 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1c661befa49a registry "/entrypoint.sh /etc/" 4 minutes ago Up 4 minutes 0.0.0.0:5000->5000/tcp myregistry [root@linux-node2 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE registry latest d1e32b95d8e8 2 weeks ago 33.17 MB 192.168.74.21:5000/charlesedu/myjumperver latest 0b5196012b2d 10 weeks ago 146.6 MB jumpserver latest 0b5196012b2d 10 weeks ago 146.6 MB centos latest 0584b3d2cf6d 3 months ago 196.5 MB redis latest 0d1cbfaa41da 5 months ago 185 MB ubuntu
七、docker扩展
docker资源隔离
linux kernel namespace: PID net IPC mnt uts:容器用于独立的主机名和域名 user
docker的集群管理工具:
swarm mesos k8s
[root@linux-node1 ~]# ip netns li #查看namespace
使用网桥的方式来做的
[root@linux-node1 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242349ec77f no veth12c84a4 veth39a6e83 veth40839bb veth7c5f3eb veth984e4d5 veth9e44c33 veth9f0e50b vetha7258e1 vethaeeb6ad vethb0a0f42 vethbbebad2 vethbf738ce vethc3abfc9 vethc931d52 vethebd9674 vethfd64124 virbr0 8000.000000000000 yes
docker的资源可以在启动的时候做限制
shipyard:docker的dashboard的管理界面,在使用的时候需要启动235端口,在docker的配置文件中修改docker的启动设置:
编辑/etc/sysconfig/docker文件
在docker的配置文件中进行配置:/etc/sysconfig/docker OPTIONS='--selinux-enabled --log-driver=journald --signature-verification=false -H tcp://0.0.0.0:235 -H unix://var/run/docker.sock' [root@linux-node2 ~]# netstat -tulp|grep docker tcp6 0 0 [::]:235 [::]:* LISTEN 8759/dockerd-curren
这样就可以获取docker的状态信息了,还可以在监控的时候使用
curl -s http://192.168.74.21:235/info |python -mjson.tool #这样就可以获取docker的状态信息了,可以在监控的时候使用 { "Architecture": "x86_64", "BridgeNfIp6tables": false, "BridgeNfIptables": false, "CPUSet": true, "CPUShares": true, "CgroupDriver": "systemd", "ClusterAdvertise": "", "ClusterStore": "", "Containers": 1, "ContainersPaused": 0, "ContainersRunning": 0, "ContainersStopped": 1, "CpuCfsPeriod": true, "CpuCfsQuota": true, "Debug": false, "DefaultRuntime": "docker-runc", "DockerRootDir": "/var/lib/docker", "Driver": "devicemapper", "DriverStatus": [ [ "Pool Name", "docker-253:0-104702441-pool" ], [ "Pool Blocksize", "65.54 kB" ], [ "Base Device Size", "10.74 GB" ], [ "Backing Filesystem", "xfs" ], [ "Data file", "/dev/loop0" ], [ "Metadata file", "/dev/loop1" ], [ "Data Space Used", "921.8 MB" ], [ "Data Space Total", "107.4 GB" ], [ "Data Space Available", "6.841 GB" ], [ "Metadata Space Used", "1.651 MB" ], [ "Metadata Space Total", "2.147 GB" ], [ "Metadata Space Available", "2.146 GB" ], [ "Thin Pool Minimum Free Space", "10.74 GB" ], [ "Udev Sync Supported", "true" ], [ "Deferred Removal Enabled", "false" ], [ "Deferred Deletion Enabled", "false" ], [ "Deferred Deleted Device Count", "0" ], [ "Data loop file", "/var/lib/docker/devicemapper/devicemapper/data" ], [ "Metadata loop file", "/var/lib/docker/devicemapper/devicemapper/metadata" ], [ "Library Version", "1.02.107-RHEL7 (2015-10-14)" ] ], "ExecutionDriver": "", "ExperimentalBuild": false, "HttpProxy": "", "HttpsProxy": "", "ID": "KOUC:LWKS:IF4V:6AKD:3JBI:ZZDD:KLPZ:RXHD:RPET:7TJV:AVVS:6LUI", "IPv4Forwarding": true, "Images": 13, "IndexServerAddress": "https://index.docker.io/v1/", "IndexServerName": "docker.io", "KernelMemory": true, "KernelVersion": "3.10.0-327.el7.x86_64", "Labels": null, "LiveRestoreEnabled": false, "LoggingDriver": "journald", "MemTotal": 471347200, "MemoryLimit": true, "NCPU": 1, "NEventsListener": 0, "NFd": 17, "NGoroutines": 24, "Name": "linux-node2", "NoProxy": "", "OSType": "linux", "OomKillDisable": true, "OperatingSystem": "CentOS Linux 7 (Core)", "PkgVersion": "docker-common-1.12.5-14.el7.centos.x86_64", "Plugins": { "Authorization": null, "Network": [ "bridge", "null", "host", "overlay" ], "Volume": [ "local" ] }, "Registries": [ { "Name": "docker.io", "Secure": true } ], "RegistryConfig": { "IndexConfigs": { "docker.io": { "Mirrors": [ "http://a5015968.m.daocloud.io" ], "Name": "docker.io", "Official": true, "Secure": true } }, "InsecureRegistryCIDRs": [ "127.0.0.0/8" ], "Mirrors": [ "http://a5015968.m.daocloud.io" ] }, "Runtimes": { "docker-runc": { "path": "/usr/libexec/docker/docker-runc-current" }, "runc": { "path": "docker-runc" } }, "SecurityOptions": [ "seccomp", "selinux" ], "ServerVersion": "1.12.5", "SwapLimit": true, "Swarm": { "Cluster": { "CreatedAt": "0001-01-01T00:00:00Z", "ID": "", "Spec": { "CAConfig": {}, "Dispatcher": {}, "Orchestration": {}, "Raft": {}, "TaskDefaults": {} }, "UpdatedAt": "0001-01-01T00:00:00Z", "Version": {} }, "ControlAvailable": false, "Error": "", "LocalNodeState": "inactive", "Managers": 0, "NodeAddr": "", "NodeID": "", "Nodes": 0, "RemoteManagers": null }, "SystemStatus": null, "SystemTime": "2017-02-07T18:21:00.161333495+08:00" }
docker的使用:写各种dockerfile
1.规划 2.基础镜像 centos yum install wget 3.centos/Dockerfile epel.repo
进程管理使用:supervisord.conf
使用supervisord 是一个进程管理工具,可以保证进行挂掉之后起来;
一般python的API都是使用supervisord来管理的;