Docker介绍
什么是容器
Linux容器是与系统其他部分隔离开的一系列进程,从另一个系统镜像运行,并由该镜像提供支持进程所需的全部文件。
容器镜像包含了应用的所有依赖项,因而在从开发到测试再到生产的整个过程中,它都具有可移植性和一致性。
来源:https://www.redhat.com/zh/topics/containers/whats-a-linux-container
容器就是虚拟化吗?
虚拟化使得许多操作系统可同时在单个系统上运行。
容器只能共享操作系统内核,将应用进程与系统其他部分,隔离开。
容器和虚拟化的区别
linux容器技术,容器虚拟化和kvm虚拟化的区别
kvm虚拟化:需要硬件的支持,需要模拟硬件,可以运行不同的操作系统,启动时间分钟级(开机启动流程)
容器虚拟化:不需要硬件的支持。不需要模拟硬件,共用宿主机的内核,启动时间秒级(没有开机启动流程)
容器总结:
(1)与宿主机使用同一个内核,性能损耗小;
(2)不需要指令级模拟;
(3)容器可以在CPU核心的本地运行指令,不需要任何专门的解释机制;
(4)避免了准虚拟化和系统调用替换中的复杂性;
(5)轻量级隔离,在隔离的同时还提供共享机制,以实现容器与宿主机的资源共享。
容器技术的发展过程
chroot技术,新建一个子系统
chroot,即 change root directory (更改 root 目录)。在 linux 系统中,系统默认的目录结构都是以 `/`,即是以根 (root) 开始的。而在使用 chroot 之后,系统的目录结构将以指定的位置作为 `/` 位置。
参考资料:https://www.ibm.com/developerworks/cn/linux/l-cn-chroot/
使用chroot监狱限制SSH用户访问指定目录和使用指定命令:https://linux.cn/article-8313-1.html
lxc部署
Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。
安装lxc
需要使用epel源
#安装epel源
yum install epel-release -y
#编译epel源配置文件
vi /etc/yum.repos.d/epel.repo [epel] name=Extra Packages for Enterprise Linux 7 - $basearch baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-7&arch=$basearch failovermethod=priority enabled=1 gpgcheck=1 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 [epel-debuginfo] name=Extra Packages for Enterprise Linux 7 - $basearch - Debug baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch/debug #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-debug-7&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 gpgcheck=1 [epel-source] name=Extra Packages for Enterprise Linux 7 - $basearch - Source baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/SRPMS #mirrorlist=https://mirrors.fedoraproject.org/metalink?repo=epel-source-7&arch=$basearch failovermethod=priority enabled=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 gpgcheck=1
##安装lxc
yum install lxc-* -y yum install libcgroup* -y yum install bridge-utils.x86_64 -y
交接网卡
[root@controller ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE=Ethernet BOOTPROTO=none NAME=eth0 DEVICE=eth0 ONBOOT=yes BRIDGE=br0 [root@controller ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0 TYPE=Bridge BOOTPROTO=static NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=10.0.0.11 NETMASK=255.255.255.0 GATEWAY=10.0.0.254 DNS1=223.5.5.5
修改lxc默认配置
vi /etc/lxc/default.conf 修改第2行为:lxc.network.link = br0
启动cgroup服务
systemctl enable cgconfig.service
systemctl start cgconfig.service
创建lxc容器
方法1: lxc-create -t download -n centos7 -- --server mirrors.tuna.tsinghua.edu.cn/lxc-images -d centos -r 7 -a amd64 方法2: lxc-create -t centos -n test
为容器指定ip和网关
vi /var/lib/lxc/centos7/config lxc.network.name = eth0 lxc.network.ipv4 = 10.0.0.111/24 lxc.network.ipv4.gateway = 10.0.0.254
启动容器
lxc-start -n centos7
lxc实操
#查看虚拟机
[root@docker opt]# lxc-ls
centos7
修改子系统root密码
[root@docker opt]# chroot /var/lib/lxc/centos7/rootfs passwd Changing password for user root. New password: BAD PASSWORD: The password is shorter than 8 characters Retype new password: passwd: all authentication tokens updated successfully.
启动子系统
[root@docker opt]# lxc-start -n centos7 systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ -LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN) Detected virtualization lxc. Detected architecture x86-64. Welcome to CentOS Linux 7 (Core)!
检测
[root@docker ~]# lxc-checkconfig Kernel configuration not found at /proc/config.gz; searching... Kernel configuration found at /boot/config-3.10.0-327.el7.x86_64 --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled newuidmap is not installed newgidmap is not installed Network namespace: enabled Multiple /dev/pts instances: enabled --- Control groups --- Cgroup: enabled Cgroup clone_children flag: enabled Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: enabled Cgroup cpuset: enabled --- Misc --- Veth pair device: enabled Macvlan: enabled Vlan: enabled Bridges: enabled Advanced netfilter: enabled CONFIG_NF_NAT_IPV4: enabled CONFIG_NF_NAT_IPV6: enabled CONFIG_IP_NF_TARGET_MASQUERADE: enabled CONFIG_IP6_NF_TARGET_MASQUERADE: enabled CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled --- Checkpoint/Restore --- checkpoint restore: enabled CONFIG_FHANDLE: enabled CONFIG_EVENTFD: enabled CONFIG_EPOLL: enabled CONFIG_UNIX_DIAG: enabled CONFIG_INET_DIAG: enabled CONFIG_PACKET_DIAG: enabled CONFIG_NETLINK_DIAG: enabled File capabilities: enabled Note : Before booting a new kernel, you can check its configuration usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
docker容器
Docker是通过内核虚拟化技术(namespaces及cgroups cpu、内存、磁盘io等)来提供容器的资源隔离与安全保障等。由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率。
docker的主要目标是"Build,Ship and Run any App,Angwhere",构建,运输,处处运行
构建:做一个docker镜像
运输:docker pull
运行:启动一个容器
每一个容器,他都有自己的文件系统rootfs.
kvm解决了硬件和操作系统之间的依赖
docker解决了软件和操作系统环境之间的依赖,能够让独立服务或应用程序在不同的环境中,得到相同的运行结果。
docker容器是一种轻量级、可移植、自包含的软件打包技术,使应用程序可以在几乎任何地方以相同的方式运行。开发人员在自己笔记本上创建并测试好的容器,无需任何修改就能够在生产系统的虚拟机、物理服务器或公有云主机上运行。
Docker的部署
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo yum install docker-ce -y
docker的主要组成部分
docker是传统的CS架构分为docker client和docker server,向mysql一样
命令:docker version
[root@controller ~]# docker version Client: Version: 17.12.0-ce API version: 1.35 Go version: go1.9.2 Git commit: c97c6d6 Built: Wed Dec 27 20:10:14 2017 OS/Arch: linux/amd64 Server: Engine: Version: 17.12.0-ce API version: 1.35 (minimum version 1.12) Go version: go1.9.2 Git commit: c97c6d6 Built: Wed Dec 27 20:12:46 2017 OS/Arch: linux/amd64 Experimental: false
设置docker远程执行
systemd详解:http://www.ruanyifeng.com/blog/2016/03/systemd-tutorial-part-two.html
在linux-node1设置
vim /usr/lib/systemd/system/docker.service ExecStart=/usr/bin/dockerd -H unix:///var/run/docker.sock -H tcp://10.0.0.11:2375
systemctl daemon-reload systemctl restart docker.service
ps -ef检查
在linux-node2设置
wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.ustc.edu.cn/docker-ce/linux/centos/docker-ce.repo sed -i 's#download.docker.com#mirrors.ustc.edu.cn/docker-ce#g' /etc/yum.repos.d/docker-ce.repo yum install docker-ce -y docker -H 10.0.0.11 info --- 远程执行 info 展示docker的信息
docker主要组件有:镜像、容器、仓库
启动第一个容器
命令:docker run -d -p 80:80 nginx
实操:
[root@docker-node1 ~]# docker run -d -p 80:80 nginx Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx e7bb522d92ff: Pull complete 6edc05228666: Pull complete cd866a17e81f: Pull complete Digest: sha256:285b49d42c703fdf257d1e2422765c4ba9d3e37768d6ea83d7fe2043dad6e63d Status: Downloaded newer image for nginx:latest e1cb110a537622e4a5c885161bca69478adc5d218e6eb4e0307c7fe0c1350012 #run: 创建并运行一个容器, #-d:放在后台 #-p:端口映射 #80:80:前面是宿主机的,后面是容器的 #nginx:镜像的名字
docker的镜像管理
搜索镜像
命令:docker search
实操:
[root@docker-node1 ~]# docker search centos NAME(镜像名) DESCRIPTION(说明) STARS(送心数) OFFICIAL(是否是官方的) AUTOMATED(是否自动) centos The official build of CentOS. 3992 [OK]
获取镜像
命令:docker pull
实操:
[root@docker-node1 ~]# docker pull centos --- 拉取一个镜像centos(不指定版本默认为最新版,只写名字默认在官方拉取) Using default tag: latest latest: Pulling from library/centos af4b0a2388c6: Pull complete Digest: sha256:2671f7a3eea36ce43609e9fe7435ade83094291055f1c96d9d1d1d7c0b986a5d Status: Downloaded newer image for centos:latest [root@docker-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest ff426288ea90 3 weeks ago 207MB nginx latest 3f8a4339aadd 5 weeks ago 108MB
拉取非官网的镜像:
[root@docker-node1 ~]# docker pull index.tenxcloud.com/tenxcloud/httpd:2.4 2.4: Pulling from tenxcloud/httpd 8b87079b7a06: Downloading 11.53MB/51.36MB a3ed95caeb02: Download complete 0c30bf087cf7: Download complete 79f2be53847c: Downloading 11.14MB/11.7MB 7063c4b35837: Download complete 5c27df81ae71: Download complete
镜像加速
镜像加速器:阿里云加速器,daocloud加速器,中科大加速器,Docker 中国官方镜像加速:https://registry.docker-cn.com
镜像加速配置:
vi /etc/docker/daemon.json { "registry-mirrors": ["https://registry.docker-cn.com"] }
第三方docker镜像仓库,使用方法
docker pull index.tenxcloud.com/tenxcloud/httpd:latest
镜像操作
查看镜像
docker images
删除镜像
docker rmi 例子:docker image rm centos:latest
实操:
[root@docker ~]# docker image rm centos:latest (名字:版本) Untagged: centos:latest Untagged: centos@sha256:2671f7a3eea36ce43609e9fe7435ade83094291055f1c96d9d1d1d7c0b986a5d Deleted: sha256:ff426288ea903fcf8d91aca97460c613348f7a27195606b45f19ae91776ca23d Deleted: sha256:e15afa4858b655f8a5da4c4a41e05b908229f6fab8543434db79207478511ff7 [root@docker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx latest 3f8a4339aadd 5 weeks ago 108MB
导出镜像
docker save 例子:docker image save centos > docker-centos7.4.tar.gz
实操:
[root@docker ~]# docker image save centos > docker-centos7.4.tar.gz [root@docker ~]# ls docker-centos7.4.tar.gz docker-centos7.4.tar.gz
导入镜像
docker load 例子:docker image load -i docker-centos7.4.tar.gz
实操:
[root@docker ~]# docker image load -i docker-centos7.4.tar.gz e15afa4858b6: Loading layer 215.8MB/215.8MB Loaded image: centos:latest [root@docker ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos latest ff426288ea90 3 weeks ago 207MB nginx latest 3f8a4339aadd 5 weeks ago 108MB
查看镜像详细信息
[root@docker ~]# docker image inspect centos [ { "Id": "sha256:ff426288ea903fcf8d91aca97460c613348f7a27195606b45f19ae91776ca23d", "RepoTags": [ "centos:latest" ], "RepoDigests": [], "Parent": "", "Comment": "", "Created": "2018-01-08T19:58:27.63047329Z", "Container": "dd31c81a4b47b90a14cf6d1c7389465060e390f12a0b71189d181a0458d8443f", "ContainerConfig": { "Hostname": "dd31c81a4b47", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD ["/bin/bash"]" ], "ArgsEscaped": true, "Image": "sha256:5a28642a68c5af8083107fca9ffbc025179211209961eae9b1f40f928331fa90", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "build-date": "20180107", "license": "GPLv2", "name": "CentOS Base Image", "vendor": "CentOS" } }, "DockerVersion": "17.06.2-ce", "Author": "", "Config": { "Hostname": "", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ], "ArgsEscaped": true, "Image": "sha256:5a28642a68c5af8083107fca9ffbc025179211209961eae9b1f40f928331fa90", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "build-date": "20180107", "license": "GPLv2", "name": "CentOS Base Image", "vendor": "CentOS" } }, "Architecture": "amd64", "Os": "linux", "Size": 207191530, "VirtualSize": 207191530, "GraphDriver": { "Data": { "DeviceId": "10", "DeviceName": "docker-8:2-667845-6de21ff18b07a4a121111b78d105af3ae3d1eccf0d5bcf3dff957e3640a79dac", "DeviceSize": "10737418240" }, "Name": "devicemapper" }, "RootFS": { "Type": "layers", "Layers": [ "sha256:e15afa4858b655f8a5da4c4a41e05b908229f6fab8543434db79207478511ff7" ] }, "Metadata": { "LastTagTime": "0001-01-01T00:00:00Z" } } ]
Docker的容器管理
启动一个容器
docker run -d -p 80:80 nginx
查看启动的容器(两种方法):
[root@docker-node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 75516b38df19 nginx "nginx -g 'daemon of…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp inspiring_euler [root@docker-node1 ~]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 75516b38df19 nginx "nginx -g 'daemon of…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp inspiring_euler
显示所有状态的容器
[root@docker-node1 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 75516b38df19 nginx "nginx -g 'daemon of…" 3 hours ago Up 3 hours 0.0.0.0:80->80/tcp inspiring_euler e1cb110a5376 nginx "nginx -g 'daemon of…" 3 hours ago Exited (0) 3 hours ago thirsty_brattain
只显示容器id
[root@docker-node1 ~]# docker ps -a -q
7cef098bebc7
75516b38df19
查看容器ip
docker container inspect id或name
[root@docker-node1 ~]# docker container inspect 75516b38df19 [ { "Id": "75516b38df194d00fbb2d5ce51316f621f76a1037a0fdf1d578d14498a68d8a3", "Created": "2018-01-31T12:12:06.387035752Z", "Path": "nginx", "Args": [ "-g", "daemon off;" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 19388, "ExitCode": 0, "Error": "", "StartedAt": "2018-01-31T12:12:06.710448922Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:3f8a4339aadda5897b744682f5f774dc69991a81af8d715d37a616bb4c99edf5", "ResolvConfPath": "/var/lib/docker/containers/75516b38df194d00fbb2d5ce51316f621f76a1037a0fdf1d578d14498a68d8a3/resolv.conf", "HostnamePath": "/var/lib/docker/containers/75516b38df194d00fbb2d5ce51316f621f76a1037a0fdf1d578d14498a68d8a3/hostname", "HostsPath": "/var/lib/docker/containers/75516b38df194d00fbb2d5ce51316f621f76a1037a0fdf1d578d14498a68d8a3/hosts", "LogPath": "/var/lib/docker/containers/75516b38df194d00fbb2d5ce51316f621f76a1037a0fdf1d578d14498a68d8a3/75516b38df194d00fbb2d5ce51316f621f76a1037a0fdf1d578d14498a68d8a3-json.log", "Name": "/inspiring_euler", "RestartCount": 0, "Driver": "devicemapper", "Platform": "linux", "MountLabel": "", "ProcessLabel": "", "AppArmorProfile": "", "ExecIDs": null, "HostConfig": { "Binds": null, "ContainerIDFile": "", "LogConfig": { "Type": "json-file", "Config": {} }, "NetworkMode": "default", "PortBindings": { "80/tcp": [ { "HostIp": "", "HostPort": "80" } ] }, "RestartPolicy": { "Name": "no", "MaximumRetryCount": 0 }, "AutoRemove": false, "VolumeDriver": "", "VolumesFrom": null, "CapAdd": null, "CapDrop": null, "Dns": [], "DnsOptions": [], "DnsSearch": [], "ExtraHosts": null, "GroupAdd": null, "IpcMode": "shareable", "Cgroup": "", "Links": null, "OomScoreAdj": 0, "PidMode": "", "Privileged": false, "PublishAllPorts": false, "ReadonlyRootfs": false, "SecurityOpt": null, "UTSMode": "", "UsernsMode": "", "ShmSize": 67108864, "Runtime": "runc", "ConsoleSize": [ 0, 0 ], "Isolation": "", "CpuShares": 0, "Memory": 0, "NanoCpus": 0, "CgroupParent": "", "BlkioWeight": 0, "BlkioWeightDevice": [], "BlkioDeviceReadBps": null, "BlkioDeviceWriteBps": null, "BlkioDeviceReadIOps": null, "BlkioDeviceWriteIOps": null, "CpuPeriod": 0, "CpuQuota": 0, "CpuRealtimePeriod": 0, "CpuRealtimeRuntime": 0, "CpusetCpus": "", "CpusetMems": "", "Devices": [], "DeviceCgroupRules": null, "DiskQuota": 0, "KernelMemory": 0, "MemoryReservation": 0, "MemorySwap": 0, "MemorySwappiness": null, "OomKillDisable": false, "PidsLimit": 0, "Ulimits": null, "CpuCount": 0, "CpuPercent": 0, "IOMaximumIOps": 0, "IOMaximumBandwidth": 0 }, "GraphDriver": { "Data": { "DeviceId": "8", "DeviceName": "docker-8:2-667845-d7559a9d1629b837315264d5191776a3583b745cbb270be66f15126659ea266d", "DeviceSize": "10737418240" }, "Name": "devicemapper" }, "Mounts": [], "Config": { "Hostname": "75516b38df19", "Domainname": "", "User": "", "AttachStdin": false, "AttachStdout": false, "AttachStderr": false, "ExposedPorts": { "80/tcp": {} }, "Tty": false, "OpenStdin": false, "StdinOnce": false, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "NGINX_VERSION=1.13.8-1~stretch", "NJS_VERSION=1.13.8.0.1.15-1~stretch" ], "Cmd": [ "nginx", "-g", "daemon off;" ], "ArgsEscaped": true, "Image": "nginx", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>" }, "StopSignal": "SIGTERM" }, "NetworkSettings": { "Bridge": "", "SandboxID": "33eb47f2321af718ee6a7564f8ae8c9841719051efebb2dfdb8a206d19e83004", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": { "80/tcp": [ { "HostIp": "0.0.0.0", "HostPort": "80" } ] }, "SandboxKey": "/var/run/docker/netns/33eb47f2321a", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "a4a179b29fb9cda0c6332579460dddc5fbc6e7f29dd5608ae9f5742701d4202e", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:02", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "12e101b4dd9dd0078bab6ed9ce9aaf2d7cca2e00e4a66b5629f088732d6698d0", "EndpointID": "a4a179b29fb9cda0c6332579460dddc5fbc6e7f29dd5608ae9f5742701d4202e", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } } } } ]
停止容器
docker container stop id或name docker container kill id或name
实操:
[root@docker-node1 ~]# docker container stop 75516b38df19 75516b38df19 [root@docker-node1 ~]# docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@docker-node1 ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 75516b38df19 nginx "nginx -g 'daemon of…" 3 hours ago Exited (0) 10 seconds ago inspiring_euler e1cb110a5376 nginx "nginx -g 'daemon of…" 3 hours ago Exited (0) 3 hours ago thirsty_brattain
总结:docker容器内的第一个进程必须一直处于前台运行的状态,否则这个容器,就会处于退出状态!
删除已关闭的容器
[root@docker-node1 ~]# docker container rm e1cb110a5376 e1cb110a5376
批量删除:
docker rm -f `docker ps -a -q` -- 强制删除全部,包括启动中的
[root@docker-node1 ~]# docker rm `docker ps -a -q` #只删除关闭状态的 7cef098bebc7 75516b38df19
交互式进入容器,分配终端
docker run -it nginx:latest /bin/bash
-i -t:--interactive --tty(直接进入容器)
[root@docker-node1 ~]# docker run -it nginx:latest /bin/bash root@7cef098bebc7:/# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr
进入容器的方法
[root@docker-node1 opt]# docker run -it --name erlianzhang centos:latest
[root@b07f6aad08cd /]#
进入到存活的容器中
[root@docker ~]# docker attach erlianzhang
[root@b07f6aad08cd /]#
exec方式必须指定起始命令 --- 推荐使用exec
[root@docker ~]# docker exec -it erlianzhang /bin/bash [root@abcadd1250cb /]# ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 16:14 pts/0 00:00:00 /bin/bash root 13 0 0 16:16 pts/1 00:00:00 /bin/bash root 25 13 0 16:16 pts/1 00:00:00 ps -ef
注意:进入容器中第一个命令一定要让容器夯住,否则会变成退出状态
暂时退出容器:ctrl+p,ctrl+q
回到容器:docker attach id或name
docker容器的网络访问
指定映射
-p hostPort:containerPort -p ip:hostPort:containerPort -p ip::containerPort -p hostPort:containerPort:udp -p 81:80 –p 443:443
随机映射
docker run -P
实操
docker run -d -p 888:80 nginx:latest
docker run -d -p 10.0.0.11:80:80 nginx:latest
[root@docker-node1 opt]# docker run -d -p 888:80 nginx:latest 1b177e8c6357ed08ddabb745b902a4e577e8c25e154a4b891dfa900b108dd4bd [root@docker-node1 opt]# netstat -lntup Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1406/sshd tcp 0 0 10.0.0.11:2375 0.0.0.0:* LISTEN 19206/dockerd tcp6 0 0 :::22 :::* LISTEN 1406/sshd tcp6 0 0 :::888 :::* LISTEN 21455/docker-proxy
docker的数据卷管理
数据卷(文件或目录)
-v /data
-v src:dst
数据卷容器
--volumes-from
实操:挂载数据卷在容器宿主机
[root@docker-node1 opt]# docker run -d -p 80:80 -v /data:/usr/share/nginx/html nginx:latest 884b2c093c5c59897bd55b0dcec36c882abdc99134f8fffed4cb5decda17327d
创建数据卷
[root@docker-node1 data]# docker volume ls DRIVER VOLUME NAME local qingge
手动将容器保存为镜像(制作镜像)
命令:docker commit
特权容器
docker run --privileged -ti -e "container=docker" -v /sys/fs/cgroup:/sys/fs/cgroup centos:latest /usr/sbin/init
保存为镜像
[root@docker-node1 ~]# docker commit ebfdf46f9f12 centos6-ssh sha256:b917ca49263af6d4435dc3c144c214af29c56dad7256e4de7978ffd9a7e24f39 [root@docker-node1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE centos6-ssh latest b917ca49263a 5 seconds ago 315MB httpd 2.4 2e202f453940 5 days ago 179MB centos latest ff426288ea90 3 weeks ago 207MB nginx latest 3f8a4339aadd 5 weeks ago 108MB centos 6.8 6704d778b3ba 2 months ago 195MB
dockerfile自动构建docker镜像
dockerfile主要组成部分:
基础镜像信息 FROM:centos:6.8 制作镜像操作指令 RUN yum install openssh-server -y 容器启动时执行指令 CMD ["/bin/bash"]
dockerfile常用指令:
FROM 这个镜像的妈妈是谁? (指定基础镜像)
MAINTAINER 告诉别人,谁负责养它?(指定维护者信息,可以没有)
RUN 你想让它干啥 (在命令前面加上RUN即可)
ADD 给它点创业资金 (COPY文件,会自动解压)
WORKDIR 我是cd,今天刚化了妆 (设置当前工作目录)
VOLUME 给它一个存放行李的地方(设置卷,挂载主机目录)
EXPOSE 它要打开的门是啥 (指定对外的端口)
CMD 奔跑吧,兄弟! (指定容器启动后的要干的事情)
dockerfile其他指令:
COPY 复制文件
ENV 环境变量
ENTRYPOINT 容器启动后执行的命令
实例:
此处在CMD处执行的是一个脚本,脚本内容大致是开启ssh服务并让ssh服务夯住,参数是-D,开启httpd服务
[root@docker-node1 ~]# cat /opt/base/Dockerfile FROM centos:6.8 RUN yum install wget unzip php* httpd openssh-server -y RUN cd /var/www/html/ && wget http://static.kodcloud.com/update/download/kodexplorer4.25.zip && unzip kodexplorer4.25.zip RUN echo 'root:123456'|chpasswd RUN echo 'ServerName 127.0.0.1:80' >>/etc/httpd/conf/httpd.conf RUN /etc/init.d/sshd start RUN chmod -Rf 777 /var/www/html/ RUN sed 's#Options Indexes FollowSymLinks#Options FollowSymLinks#g' /etc/httpd/conf/httpd.conf -i COPY init.sh /init.sh EXPOSE 80/tcp EXPOSE 22/tcp CMD ["/bin/bash","/init.sh"] [root@docker-node1 ~]# ll /opt/base/ total 8 -rw-r--r-- 1 root root 528 Feb 1 06:16 Dockerfile -rw-r--r-- 1 root root 82 Feb 1 03:37 init.sh [root@docker-node1 ~]# docker image build -t centos6-yun .
docker image build -t centos6-yun /opt/base/Dockerfile
docker image build -t 指定一个自动构建的镜像标签 Dockerfile文件路径
参考其他的dockerfile
官方dockerfile或者时速云镜像广场
容器间的互联
docker run -d -p 80:80 nginx docker run -it --link quirky_brown:web01 qstack/centos-ssh /bin/bash ping web01
使用docker运行zabbix-server
docker run --name mysql-server -t -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="zabbix_pwd" -e MYSQL_ROOT_PASSWORD="root_pwd" -d mysql:5.7 --character-set-server=utf8 --collation-server=utf8_bin docker run --name zabbix-java-gateway -t -d zabbix/zabbix-java-gateway:latest docker run --name zabbix-server-mysql -t -e DB_SERVER_HOST="mysql-server" -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="zabbix_pwd" -e MYSQL_ROOT_PASSWORD="root_pwd" -e ZBX_JAVAGATEWAY="zabbix-java-gateway" --link mysql-server:mysql --link zabbix-java-gateway:zabbix-java-gateway -p 10051:10051 -d zabbix/zabbix-server-mysql:latest docker run --name zabbix-web-nginx-mysql -t -e DB_SERVER_HOST="mysql-server" -e MYSQL_DATABASE="zabbix" -e MYSQL_USER="zabbix" -e MYSQL_PASSWORD="zabbix_pwd" -e MYSQL_ROOT_PASSWORD="root_pwd" --link mysql-server:mysql --link zabbix-server-mysql:zabbix-server -p 80:80 -d zabbix/zabbix-web-nginx-mysql:latest
docker私有仓库
普通的registry
启动registry容器
docker run -d -p 5000:5000 --restart=always --name registry -v /opt/myregistry:/var/lib/registry registry
修改配置文件
/etc/docker/daemon.json
{ "registry-mirrors": ["https://registry.docker-cn.com"], "insecure-registries": ["10.0.0.11:5000"] }
"insecure-registries": ["10.0.0.11:5000"] ---- 将https转换成http
重启docker服务
systemctl restart docker.service
为镜像打标签
docker tag centos6-yun:latest 10.0.0.11:5000/erlianzhang/centos6-yun:latest
push推送镜像
docker push 10.0.0.11:5000/erlianzhang/centos6-yun:latest
带basic认证的registry
mkdir /opt/registry-var/auth/ -p htpasswd -Bbn erlianzhang 123456 >> /opt/registry-var/auth/htpasswd docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
实操
yum install httpd-tools.x86_64 -y [root@docker-node1 ~]# mkdir /opt/registry-var/auth/ -p ASSWD_PATH=/auth/htpasswd registry
[root@docker-node1 ~]# htpasswd -Bbn erlianzhang 123456 >> /opt/registry-var/auth/htpassw [root@docker-node1 ~]# docker run -d -p 5000:5000 -v /opt/registry-var/auth/:/auth/ -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry 589820e671fa51114bf9ccf143375bce7351a80f7035e571f4e8524a1096edbb [root@docker-node1 ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 589820e671fa registry "/entrypoint.sh /etc…" 11 seconds ago Up 11 seconds 0.0.0.0:5000->5000/tcp confident_visvesvaraya [root@docker-node1 ~]# docker push 10.0.0.11:5000/erlianzhang/centos6-yun:latest --- 不验证就不能上传 The push refers to repository [10.0.0.11:5000/erlianzhang/centos6-yun] f8508dc392c8: Preparing f85b7909a4bc: Preparing 8b2d1868cde8: Preparing ad87982f4b1b: Preparing ac521dbe8cd3: Preparing 3d169f2d5cff: Waiting 6bad9d62f12a: Waiting f28db075daf0: Waiting e00c9229b481: Waiting no basic auth credentials [root@docker-node1 ~]# docker login 10.0.0.11:5000 --- 验证一下 Username: erlianzhang Password: Login Succeeded [root@docker-node1 ~]# docker push 10.0.0.11:5000/erlianzhang/centos6-yun:latest --- 再次上传就可以了 The push refers to repository [10.0.0.11:5000/erlianzhang/centos6-yun] f8508dc392c8: Pushed f85b7909a4bc: Pushed 8b2d1868cde8: Pushed ad87982f4b1b: Pushed ac521dbe8cd3: Pushed 3d169f2d5cff: Pushed 6bad9d62f12a: Pushed f28db075daf0: Pushed e00c9229b481: Pushed latest: digest: sha256:46e0409381ef7c5922bc5c37b5888015ab415c0e7248e463323db361318e93bf size: 2205
验证
[root@docker-node1 ~]# cat .docker/config.json { "auths": { "10.0.0.11:5000": { "auth": "b2xkYm95OjEyMzQ1Ng==" } }, "HttpHeaders": { "User-Agent": "Docker-Client/17.12.0-ce (linux)" } }
docker-compose(单机版的容器编排工具)
docker-compose简介
一句话:docker-compose是用来做docker的多容器控制
docker-compose 是什么
docker-compose是一个用来把docker自动化的东西。
有了docker-compose你可以把所有繁复的docker操作全都一条命令,自动化的完成。
详细指令参考:https://www.jianshu.com/p/2217cfed29d7
安装python环境
yum install -y python2-pip
详细指令:http://www.jianshu.com/p/2217cfed29d7
配置pip加速
[root@docker-node1 ~]# mkdir .pip [root@docker-node1 ~]# vim ~/.pip/pip.conf [global] index-url = http://mirrors.aliyun.com/pypi/simple/ [install] trusted-host=mirrors.aliyun.com
pip install docker-compose
配置文件
该配置文件是部署wordpress博客网站的
cd my_wordpress/
vi docker-compose.yml
version: '3' services: db: image: mysql:5.7 volumes: - /data/db_data:/var/lib/mysql restart: always environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress wordpress: depends_on: - db image: wordpress:latest volumes: - /data/web_data:/var/www/html ports: - "8000:80" restart: always environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress
启动服务
#启动 docker-compose up #后台启动 docker-compose up -d
docker配合haproxy负载
灰度重启容器,防止因为更新业务全部关闭容器
安装haproxy
yum install haproxy -y
修改配置文件
vi /etc/haproxy/haproxy.cfg
global log 127.0.0.1 local2 chroot /var/lib/haproxy pidfile /var/run/haproxy.pid maxconn 4000 user haproxy group haproxy daemon stats socket /var/lib/haproxy/stats level admin defaults mode http log global option httplog option dontlognull option http-server-close option forwardfor except 127.0.0.0/8 option redispatch retries 3 timeout http-request 10s timeout queue 1m timeout connect 10s timeout client 1m timeout server 1m timeout http-keep-alive 10s timeout check 10s maxconn 3000 listen stats mode http bind 0.0.0.0:8888 stats enable stats uri /haproxy-status stats auth admin:123456 frontend frontend_www_example_com bind 10.0.0.11:8000 mode http option httplog log global default_backend backend_www_example_com backend backend_www_example_com option forwardfor header X-REAL-IP option httpchk HEAD / HTTP/1.0 balance roundrobin server web-node1 10.0.0.11:32768 check inter 2000 rise 30 fall 15 server web-node2 10.0.0.11:32769 check inter 2000 rise 30 fall 15
启动服务
systemctl start haproxy
安装socat
yum install socat.x86_64 -y echo "disable server backend_www_example_com/web-node3"|socat stdio /var/lib/haproxy/stats echo "enable server backend_www_example_com/web-node3"|socat stdio /var/lib/haproxy/stats
利用测试页测试
<html> <head> <title>PHP测试</title> </head> <body> <?php echo '<p>Hello World </p>'; ?> <?php echo "访问的服务器地址是:"."<fontcolor=red>".$_SERVER['SERVER_ADDR']."</font>"."<br>"; echo"访问的服务器域名是:"."<fontcolor=red>".$_SERVER['SERVER_NAME']."</font>"."<br>"; ?> </body> </html>
Docker网络类型
类型 |
说明 |
None |
不为容器配置任何网络功能,没有网络 --net=none |
Container |
与另一个运行中的容器共享Network Namespace,--net=container:containerID |
Host |
与主机共享Network Namespace,--net=host |
Bridge |
Docker设计的NAT网络模型(默认类型) |
Bridge默认docker网络隔离基于网络命名空间,在物理机上创建docker容器时会为每一个docker容器分配网络命名空间,并且把容器IP桥接到物理机的虚拟网桥上。
不为容器配置网络功能
此模式下创建容器是不会为容器配置任何网络参数的,如:容器网卡、IP、通信路由等,全部需要自己去配置。
[root@docker01 ~]# docker run -it --network none busybox:latest /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever
与其他容器共享网络配置(Container)
此模式和host模式很类似,只是此模式创建容器共享的是其他容器的IP和端口而不是物理机,此模式容器自身是不会配置网络和端口,创建此模式容器进去后,你会发现里边的IP是你所指定的那个容器IP并且端口也是共享的,而且其它还是互相隔离的,如进程等。
[root@docker01 ~]# docker run -it --network container:mywordpress_db_1 busybox:latest /bin/sh / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 105: eth0@if106: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0 valid_lft forever preferred_lft forever
使用宿主机网络
此模式创建的容器没有自己独立的网络命名空间,是和物理机共享一个Network Namespace,并且共享物理机的所有端口与IP,并且这个模式认为是不安全的。、
[root@docker01 ~]# docker run -it --network host busybox:latest /bin/sh
查看网络列表
[root@docker01 ~]# docker network list NETWORK ID NAME DRIVER SCOPE b15e8a720d3b bridge bridge local 345d65b4c2a0 host host local bc5e2a32bb55 mywordpress_default bridge local ebf76eea91bb none null local
用PIPEWORK为docker容器配置独立IP
参考文档:http://blog.csdn.net/design321/article/details/48264825
官方网站:https://github.com/jpetazzo/pipework
宿主环境:centos7.2
1、安装pipework
wget https://github.com/jpetazzo/pipework/archive/master.zip unzip master.zip cp pipework-master/pipework /usr/local/bin/ chmod +x /usr/local/bin/pipework
2、配置网桥连接
安装桥接工具
yum install bridge-utils.x86_64 -y
修改网卡配置,实现桥接
# 修改eth0配置,让br0实现桥接 [root@docker01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0 TYPE=Ethernet BOOTPROTO=static NAME=eth0 DEVICE=eth0 ONBOOT=yes BRIDGE=br0 [root@docker01 ~]# cat /etc/sysconfig/network-scripts/ifcfg-br0 TYPE=Bridge BOOTPROTO=static NAME=br0 DEVICE=br0 ONBOOT=yes IPADDR=10.0.0.100 NETMASK=255.255.255.0 GATEWAY=10.0.0.254 DNS1=223.5.5.5
# 重启网络 [root@docker01 ~]# /etc/init.d/network restart
3、运行一个容器镜像测试:
pipework br0 $(docker run -d -it -p 6880:80 --name httpd_pw httpd) 10.0.0.220/24@10.0.0.254
在其他主机上测试端口及连通性
[root@docker01 ~]# curl 10.0.0.220 <html><body><h1>It works!</h1></body></html> [root@docker01 ~]# ping 10.0.0.220 -c 1 PING 10.0.0.220 (10.0.0.220) 56(84) bytes of data. 64 bytes from 10.0.0.220: icmp_seq=1 ttl=64 time=0.043 ms
4、再运行一个容器,设置网路类型为none:
pipework br0 $(docker run -d -it --net=none --name test httpd:2.4) 10.0.0.221/24@10.0.0.254
进行访问测试
[root@docker01 ~]# curl 10.0.0.221 <html><body><h1>It works!</h1></body></html>
5、重启容器后需要再次指定:
pipework br0 testduliip 172.16.146.113/24@172.16.146.1 pipework br0 testduliip01 172.16.146.112/24@172.16.146.1
Docker跨主机通信之macvlan
创建macvlan网络
docker network create --driver macvlan --subnet 10.1.0.0/24 --gateway 10.1.0.254 -o parent=eth0 macvlan_1
设置eth0的网卡为混杂模式
ip link set eth0 promisc on
创建使用macvlan网络的容器
docker run -it --network macvlan_1 --ip=10.1.0.210 busybox:latest /bin/sh
基于macvlan网络,还存有overlay网络
Dcoker跨主机通信之overlay 参考文档:http://www.cnblogs.com/CloudMan6/p/7270551.html
Docker镜像的生命周期图
docker企业级镜像仓库harbor
介绍
Harbor 是一个企业级的 Docker Registry,可以实现 images 的私有存储和日志统计权限控制等功能,并支持创建多项目(Harbor 提出的概念),基于官方 Registry V2 实现。 通过地址:https://github.com/vmware/harbor/releases 可以下载最新的版本。 官方提供了两种版本:在线版和离线版。
安装步骤
容器管理
[root@docker01 harbor]# pwd /opt/harbor [root@docker01 harbor]# docker-compose stop
第一步:安装docker和docker-compose
下载harbor-offline-installer-v1.3.0.tgz
cd /opt && https://storage.googleapis.com/harbor-releases/harbor-offline-installer-v1.3.0.tgz tar xf harbor-offline-installer-v1.3.0.tgz
第二步:修改主机及web界面密码
修改harbor.cfg配置文件
[root@docker01 harbor]# vim harbor.cfg ··· hostname = 10.0.0.100 harbor_admin_password = 123456 ···
第三步:执行install.sh
[root@docker01 harbor]# ./install.sh
第四步:web登陆测试
镜像推送到仓库的指定项目
[root@docker02 ~]# docker tag centos:6.8 10.0.0.100/clsn/centos6.8:1.0 [root@docker02 ~]# [root@docker02 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE busybox latest 5b0d59026729 8 days ago 1.15MB 10.0.0.100/clsn/centos6.8 1.0 6704d778b3ba 2 months ago 195MB centos 6.8 6704d778b3ba 2 months ago 195MB [root@docker02 ~]# docker login 10.0.0.100 Username: admin Password: Login Succeeded
推送镜像
[root@docker02 ~]# docker push 10.0.0.100/clsn/centos6.8 The push refers to repository [10.0.0.100/clsn/centos6.8] e00c9229b481: Pushing 13.53MB/194.5MB
转载注明出处,写这篇很累!!!