Showing posts with label Linux. Show all posts
Showing posts with label Linux. Show all posts

Friday, January 12, 2018

AWS fix for Meltdown and Spectre not compatible w/ Centos6 official patch

https://forums.aws.amazon.com/thread.jspa?messageID=823033

- Recently published Red Hat/CentOS kernel version - kernel-2.6.32-696.18.7.el6.x86_64 is failing to boot on a para virtual instance. This is a known issues which is under investigation with Redhat. Happen to CentOS 4, 6 etc. The workaround changing grub configuration to boot to previous kernel. grub.conf says "default=0" so it is booting the newest kernel on the first entry in the file. If I could easily override this from within the web interface for AWS EC2 and tell it to boot the next entry i.e. the equivalent of "default=1" or similar
- There's a problem with this workaround when using the old official centos images since they have a product code and as such when trying to mount it on another machine we get the following error:
"Error attaching volume: The instance configuration for this AWS Marketplace product is not supported. Please see the AWS Marketplace site for more information about supported instance types, regions, and operating systems."  the fix I used was to build a specific editing instance using the exact same CentOS image that was used originally for the borked instance. https://aws.amazon.com/marketplace/library/



Tuesday, November 14, 2017

Linux Distro


Lubuntu is a nice alternative. It is based on the LXDE environment which aims to be lightweight. It's a great disto (short for distribution) for old systems (not ancient systems) as it aims to keep the impact on your system low.

Linux Mint was designed to provide a complete experience right out of the box without having to download additional packages after installing the OS. Personally I found it lighter weight than Ubuntu in the past and a crisper interface. It's a nice fit between Ubuntu and Lubuntu.

LXLE vs Lubuntu
LXDE eXtra Luxury Edition 14.04 (old name Lubuntu eXtra Life Extension)
In a nutshell, LXLE is literally stock Lubuntu LTS (Long Term Support), with:
  • about 2 dozen preconfigured PPAs for specific add-on applications, and
  • some different choices for default theme and preinstalled applications,
    • extendet PCManFM (now let open files and directories with root permissions, easier changing file names, copying directories, emptying bin with one click)
    • shortcuts for system menu, terminal and launching panel
    • after run LXLE there are 4 options for imitation interfeces from Win XP, OS X, Gnome2 and Unity, and configuration for netbooks with small screens
    • xArchiver repaced by FileRoller
    • Gpicview replaced by Mirage (light, with scale and crop functions)
    • Ubuntu One cloud replaced by Bittorrent Sync
    • Samba Client replaced by Gigolo
---
For me, the two most significant differences are:
  • LXLE track LTS instead of mainline Ubuntu. On the one hand, I'd get to avoid the Big End-of-Life Update for a lot longer (5 years vs. 9 months). On the other hand, packages aren't as current as on mainline, to avoid potential package version jumps that turn out to be showstoppers. For instance, PostgreSQL is already on 9.4 with Lubuntu 15.04, but stuck on 9.3 with LXLE 14.04.2.
  • LXLE is a "boutique" distro. While the underpinnings (Lubuntu) are well-supported, there are enough additions and tweaks that if the LXLE creators decided to cease operations tomorrow, there's a good chance that I'd have to do a fresh Lubuntu install to continue moving forward.

Monday, June 6, 2016

rhel7

systemctl
https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units

In systemd, the target of most actions are "units", which are resources that systemd knows how to manage. Units are categorized by the type of resource they represent and they are defined with files known as unit files. The type of each unit can be inferred from the suffix on the end of the file.
For service management tasks, the target unit will be service units, which have unit files with a suffix of.service. However, for most service management commands, you can actually leave off the .servicesuffix, as systemd is smart enough to know that you probably want to operate on a service when using service management commands.
Targets are special unit files that describe a system state or synchronization point. Like other units, the files that define targets can be identified by their suffix, which in this case is .target. Targets do not do much themselves, but are instead used to group other units together. LOAD: Whether the unit's configuration has been parsed by systemd. The configuration of loaded units is kept in memory.
ACTIVE: A summary state about whether the unit is active. This is usually a fairly basic way to tell if the unit has started successfully or not.
SUB: This is a lower-level state that indicates more detailed information about the unit. This often varies by unit type, state, and the actual method in which the unit runs.
Run level 3 is emulated by multi-user.target. Run level 5 is emulated by graphical.target.
service foobar startsystemctl start foobar.serviceUsed to start a service (not reboot persistent)
service foobar stopsystemctl stop foobar.serviceUsed to stop a service (not reboot persistent)
service foobar restartsystemctl restart foobar.serviceUsed to stop and then start a service
service foobar reloadsystemctl reload foobar.serviceWhen supported, reloads the config file without interrupting pending operations.
service foobar condrestartsystemctl condrestart foobar.serviceRestarts if the service is already running.
service foobar statussystemctl status foobar.serviceTells whether a service is currently running.
ls /etc/rc.d/init.d/ls /lib/systemd/system/*.service /etc/systemd/system/*.serviceUsed to list the services that can be started or stopped
chkconfig foobar onsystemctl enable foobar.serviceTurn the service on, for start at next boot, or other trigger.
chkconfig foobar offsystemctl disable foobar.serviceTurn the service off for the next reboot, or any other trigger.
chkconfig foobarsystemctl is-enabled foobar.service; echo $?Used to check whether a service is configured to start or not in the current environment.
chkconfig foobar –listls /etc/systemd/system/*.wants/foobar.serviceUsed to list what levels this service is configured on or off
chkconfig foobar –addNot needed, no equivalent.
who -r
run level
systemctl list-units --type=target list current run level/active target
-systemctl is-active foobar.service
systemctl is-failed foobar.service
if service is currently active(running)
if service has problem start
-systemctl reload-or-restart foobar.service
-systemctl list-units or systemctl
systemctl list-units -a
show active unit by defaultshow all loaded unit (active or not)
-systemctl list-units --all --state=inactive
systemctl list-units --type=service
list all available unit 
chkconfig --listsystemctl list-unit-files --type=servicelist all available unit
-systemctl cat atd.servicedisplay unit loaded in current systemd
-systemctl list-dependencies sshd.service
[--reverse|--before|--after]

-systemctl show atd.servicelow level properties of unit
systemctl list-unit-files
The state will usually be "enabled", "disabled", "static", or "masked". In this context, static means that the unit file does not contain an "install" section, which is used to enable a unit. As such, these units cannot be enabled. Usually, this means that the unit performs a one-off action or is used only as a dependency of another unit and should not be run by itself.
systemctl mask foo.service; systemctl unmask foo.service
link unit to /dev/null, make it unstartable
systemctl edit foo.service
modify unit

loginctl (logind)
journalctl (journald)

firewalld
Use firewall-cmd to manage the rules.
In order from least trusted to most trusted, the pre-defined zones within firewalld are:
  • drop: The lowest level of trust. All incoming connections are dropped without reply and only outgoing connections are possible.
  • block: Similar to the above, but instead of simply dropping connections, incoming requests are rejected with an icmp-host-prohibited or icmp6-adm-prohibited message.
  • public: Represents public, untrusted networks. You don't trust other computers but may allow selected incoming connections on a case-by-case basis.
  • external: External networks in the event that you are using the firewall as your gateway. It is configured for NAT masquerading so that your internal network remains private but reachable.
  • internal: The other side of the external zone, used for the internal portion of a gateway. The computers are fairly trustworthy and some additional services are available.
  • dmz: Used for computers located in a DMZ (isolated computers that will not have access to the rest of your network). Only certain incoming connections are allowed.
  • work: Used for work machines. Trust most of the computers in the network. A few more services might be allowed.
  • home: A home environment. It generally implies that you trust most of the other computers and that a few more services will be accepted.
  • trusted: Trust all of the machines in the network. The most open of the available options and should be used sparingly.
To use the firewall, we can create rules and alter the properties of our zones and then assign our network interfaces to whichever zones are most appropriate.

start firewall:
# systemctl start firewalld.service
Check if firewall is running:
# systemctl status firewalld
# firewall-cmd --state
Configure firewall when firewalld is not running:
# firewall-offline-cmd
Put Lockdown=yes in the config file /etc/firewalld/firewalld.conf to prevent any change to firewall rule. Or
# firewall-cmd --lockdown-on
# firewall-cmd --lockdown-off
# firewall-cmd --query-lockdown
Zones:
These information are stored in /etc/firewalld/firewalld.conf file.
# firewall-cmd --get-default-zone
# firewall-cmd --get-active-zones
# firewall-cmd --get-zones # list all available zones
Create zone:
# firewall-cmd --permanent --new-zone=new-zone
Print zone config:
# firewall-cmd --list-all # list default zone config
# firewall-cmd --zone=home --list-all
# firewall-cmd --list-all-zones # list all config
Change interfeace zone temporarily:
# firewall-cmd --zone=home --change-interface=eth0
Interface always assign to default zone, unless specified with ZONE="zone-name" in the interface cfg /etc/sysconfig/network-scripts/ifcfg-interface. Or change be changed with,
# nmcli con mod "System eth0" connection.zone zone-name 
# firewall-cmd --get-zone-of-interface=eth0
--add-interface
--remove-interface
Change default zone
# firewall-cmd --set-default-zone=home

Source
# firewall-cmd --zone=trusted --list-sources
# firewall-cmd --zone-trusted --add-source=192.168.2.0/24
--get-zone-of-source
--remove-source
--change-source

List of available service:
# firewall-cmd --get-services
detail of the service are defined under /usr/lib/firewalld/services/.
# firewall-cmd --zone=public --add-service=http --permanent
# firewall-cmd --zone=public --add-service={http,https} --permanent
# firewall-cmd --zone=public --list-services
# firewall-cmd --zone=public --remove-service=http --permanent
Add ports
# firewall-cmd --zone=public --add-port=5000/tcp --permanent
# firewall-cmd --zone=public --add-port=4990-4999/udp --permanent
# firewall-cmd --zone=public --list-ports
# firewall-cmd --zone=public --remove-port=5000/tcp --permanent
Define a service"
Create a xml file /etc/firewalld/services/service.xml, use xml under /usr/lib/firewalld/services/ as template. Remember assign correct SELinux context and file permission.
# restorecon /etc/firewalld/services/service.xml
# chmod 640 /etc/firewalld/services/service.xml
Masquerading
# firewall-cmd --zone=external --add-masquerade
# firewall-cmd --zone=external --remove-masquerade
# firewall-cmd --zone=external --query-masquerade
Port Forwarding
# firewall-cmd --zone=external --add-forward-port=port=22:proto=tcp:toport=3753:toaddr=10.0.0.1
--remove-forward-port
--query-forward-port
Direct Rules that bypass firewalld interface
information are stored in /etc/firewalld/direct.xml file.
open port 9000:
# firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -p tcp --dport 9000 -j ACCEPT
# firewall-cmd --direct --get-all-rules
direct
# firewall-cmd --runtime-to-permanent
# firewall-cmd --reload
# systemctl restart network
# systemctl restart firewalld
Rich rules
format:
# firewall-cmd [--zone=zone] --add-rich-rule='rule' [--timeout=timeval]
# firewall-cmd [--zone-zone] --query-rich-rule='rule'
# firewall-cmd [--zone=zone] --remove-rich-rule='rule'
Add modules
Instead of using a rc.local file, it is better to notify Firewalld through the /etc/modules-load.d directory.
Backup firewall rules
# iptables -S > firewalld_rules_ipv4
# ip6tables -S > firewalld_rules_ipv6

---
For the priority from highest to lowest for when and where a rule applies when a packet arrives we have:
  • Direct rules
  • Source address based zone
    • log
    • deny
    • allow
  • Interface based zone
    • log
    • deny
    • allow
  • Default zone
    • log
    • deny
    • allow
Within each log/deny/allow split of a zone the priority is:
  • Rich rule
  • Port definition
  • Service definition
---
  • The iptables service stores configuration in /etc/sysconfig/iptables while firewalld stores it in various XML files in /usr/lib/firewalld/ and /etc/firewalld/. Note that the /etc/sysconfig/iptables file does not exist as firewalld is installed by default on Red Hat Enterprise Linux.
  • With the iptables service, every single change means flushing all the old rules and reading all the new rules from /etc/sysconfig/iptables while with firewalld there is no re-creating of all the rules; only the differences are applied. Consequently, firewalld can change the settings during runtime without existing connections being lost.






















---

Tuesday, May 17, 2016

Basic SELinux Troubleshooting in CLI

SELinux isolates all processes running on the system to mitigate attacks which take advantage of privilege escalation. Privilege escalation means that a process gains more access rights than it should have.
To prevent this, SELinux enforces Mandatory Access Control (MAC) mechanism over all processes. It labels every process, file, or directory according to rules specified in a security policy known as the SELinux policy.
The SELinux policy also specifies how processes interact with each other and how they can access files and directories. SELinux denies every action that it is not explicitly allowed by the SELinux policy.
The most common causes why SELinux denies an action are:
  • processes, files, or directories are labeled with incorrect SELinux context
  • confined processes are configured in a different way than what is expected by the default SELinux policy
  • there is a bug in the SELinux policy or in an application

Troubleshooting SELinux AVC Messages on the Command Line

When SELinux denies an action, an Access Vector Cache (AVC) message is logged to the /var/log/audit/audit.log and /var/log/messages files or thejournald daemon logs it. If you suspect that SELinux denied an action that you attempted to do, follow these basic troubleshooting steps:
  1. Use the ausearch utility to find any recent AVC messages and confirm that SELinux denies the action:
    # ausearch -m AVC,USER_AVC -ts recent
    time->Thu Feb 18 14:24:24 2016
    type=AVC msg=audit(1455805464.059:137): avc:  denied  { append } for  pid=861 comm="httpd" name="error_log" dev="sdb1" ino=20747 scontext=system_u:system_r:httpd_t:s0 tcontext=system_u:object_r:var_run_t:s0 tclass=file permissive=0
    
    The -m option specifies what kind of information ausearch returns.The -ts option specifies the time stamp. For example -ts recent returns AVC messages from the last 10 minutes or -ts today returns messages from the whole day.
  2. Use the journalctl utility to view more information about the AVC message:
    # journalctl -t setroubleshoot --since= [time]
    
    Replace [time] with the time from the AVC message found in the first step. In this example, SELinux prevented the httpd process from accessing the/var/log/httpd/error_log file:
        # journalctl -t setroubleshoot --since=14:20
    -- Logs begin at Fri 2016-01-15 01:17:17 UTC, end at Thu 2016-02-18 14:25:21 UTC. --
    Feb 18 14:24:24 fedora.23.virt setroubleshoot[866]: SELinux is preventing httpd from append access on the file error_log. For complete SELinux messages. run sealert -l e9d8fa2e-3608-4ffa-9e72-31a1b85e460b
    
  3. Use the sealert utility to further inspect the AVC message:
    # sealert -l [message_ID]
    
    Replace [message_ID] with the number of the AVC message. The output will look similarly as in the examples below:
    • In this example, SELinux prevented the httpd process from accessing the /var/log/httpd/error_log file because it was incorrectly labeled with the var_log_t SELinux type:
      # sealert -l e9d8fa2e-3608-4ffa-9e72-31a1b85e460b
          SELinux is preventing httpd from open access on the file /var/log/httpd/error_log.
      
      ***** Plugin restorecon (99.5 confidence) suggests   **************************
      
      If you want to fix the label.
          /var/log/httpd/error.log default label should be httpd_log_t.
          Then you can run restorecon.
          Do
          # /sbin/restorecon -v /var/log/httpd/error_log
      
      [trimmed for clarity]
      
    • In this example, SELinux prevented the plugin-containe process from connecting to the network using the TCP protocol and from using the Bluejeans service because the mozilla_plugin_can_network_connect and mozilla_plugin_use_bluejeans Booleans were not enabled:
      # sealert -l fc46b9d4-e5a1-4738-95a7-26616d0858b0
      SELinux is preventing plugin-containe from name_connect access on the tcp_socket port 5000.
      
      *****  Plugin catchall_boolean (9.19 confidence) suggests   ******************
      
      If you want to allow mozilla plugin domain to connect to the network using TCP.
      Then you must tell SELinux about this by enabling the 'mozilla_plugin_can_network_connect' boolean.
      You can read 'mozilla_selinux' man page for more details.
      Do
      setsebool -P mozilla_plugin_can_network_connect 1
      
      *****  Plugin catchall_boolean (9.19 confidence) suggests   ******************
      
      If you want to allow mozilla plugin to use Bluejeans.
      Then you must tell SELinux about this by enabling the 'mozilla_plugin_use_bluejeans' boolean.
      You can read 'mozilla_selinux' man page for more details.
      Do
      setsebool -P mozilla_plugin_use_bluejeans 1
      
      [trimmed for clarity]
      
    • In this example, SELinux denied the passwd process to access the /home/user/output.txt file because there is no rule in the SELinux policy that allows passwd to write to files labeled with the user_home_t SELinux type:
      # sealert -l 1dd524dd-1784-44ef-b6d1-fff9238ed927
      
      SELinux is preventing passwd from write access on the file /home/user/output.txt.
      
      *****  Plugin catchall (100. confidence) suggests   **************************
      
      If you believe that passwd should be allowed write access on the output.txt file by default.
      Then you should report this as a bug.
      You can generate a local policy module to allow this access.
      Do
      allow this access for now by executing:
      # grep passwd /var/log/audit/audit.log | audit2allow -M mypol
      # semodule -i mypol.pp
      
      [trimmed for clarity]
      
  4. Perform actions according to suggestions provided by sealert. For example, use the restorecon utility to fix incorrectly labeled files or enable particular Booleans. If there is no suitable hint provided by sealert or you are not sure how to implement the suggestions, contact our support. If you believe that there is a bug in the SELinux policy, report a bug.
  5. Repeat the action you attempted to do before SELinux denied it. If SELinux is still preventing the action, report a bug.

Additional Information:

Monday, May 16, 2016

Docker




LXC vs LXD vs Docker

Linux Container technologies:
  • LXC
  • OpenVZ
  • Linux-VServer
  • FreeBSD jail
  • Solaris Zones
------------
  • Docker specializes in deploying apps (it encapsulates an app and its identity)
  • LXD specializes in deploying (Linux) Virtual Machines (it acts like a Linux virtual machine)


Accroding to RedHat, Containers using the libvirt-lxc tooling have been deprecated from RHEL7.1. Linux containers framework is now based on the docker command-line interface.
Linux containers are essentially the clone() system call, SELinux, and Cgroups; whether they are of a LXC or Docker (through libcontainer) type is mostly irrelevant as the Linux kernel itself “does” the process isolation.

--------------------
Docker Howto:
Tutorials:

Docker Commands

Here is a summary of currently available (version 0.7.1) docker commands:
attach: Attach to a running container
build:  Build a container from a Dockerfile
commit: Create a new image from a container's changes
cp:     Copy files/folders from the containers filesystem to the host path
diff:       Inspect changes on a container's filesystem
events: Get real time events from the server
export: Stream the contents of a container as a tar archive
history:    Show the history of an image
images: List images
import: Create a new filesystem image from the contents of a tarball
info:   Display system-wide information
insert: Insert a file in an image
inspect:    Return low-level information on a container
kill:       Kill a running container
load:   Load an image from a tar archive
login:  Register or Login to the docker registry server
logs:   Fetch the logs of a container
port:   Lookup the public-facing port which is NAT-ed to PRIVATE_PORT
ps:     List containers
pull:       Pull an image or a repository from the docker registry server
push:   Push an image or a repository to the docker registry server
restart:    Restart a running container
rm:     Remove one or more containers
rmi:        Remove one or more images
run:        Run a command in a new container
save:   Save an image to a tar archive
search: Search for an image in the docker index
start:  Start a stopped container
stop:   Stop a running container
tag:        Tag an image into a repository
top:        Lookup the running processes of a container
version:    Show the docker version information
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
-aattach to STDIN
-drun container in background
-hcontainer hostname
-i, --interactivekeep STDIN open even if not attached
--ip=""container ipv4 address
--link=[]add link to another container
--name=""Assign a name to the container
-P, --publish-allPublish all exposed ports to random ports
-p, --publish=[]publish a container's ports to the host
--rmAutomatically remove the container when it exists
-u, --user="<name|uid>[:<group|gid>]"username
-v, --volume=[host-src:]container-dest[:<options>]Bind mount a volume. The comma-delimited `options` are [rw|ro], [z|Z], [[r]shared|[r]slave|[r]private], and [nocopy]. The 'host-src' is an absolute path or a name value.
--volumes-from=[]Mount volumes from the specified container(s)
-w, --workdir=""Working directory inside the container
The -p flag can take a few different formats:
ip:hostPort:containerPort| ip::containerPort | hostPort:containerPort | containerPort
Essentially, you can omit either ip or hostPort, but you must always specify a containerPort to expose. Docker will automatically provide an ip and hostPort if they are omitted. Additionally, all of these publishing rules will default to tcp. If you need udp, simply tack it on to the end such as -p 1234:1234/udp.
============
Docker images are store under /var/lib/docker directory vary depending on the driver Docker is using for storage.  In most places this will be aufs but the RedHats went with devicemapper. You can manually set the storage driver with the -s or --storage-driver= option to the Docker daemon.
  • /var/lib/docker/{driver-name} will contain the driver specific storage for contents of the images.
  • /var/lib/docker/graph/<id> now only contains metadata about the image, in the json and layersize files.
In the case of aufs:
  • /var/lib/docker/aufs/diff/<id> has the file contents of the images.
  • /var/lib/docker/repositories-aufs is a JSON file containing local image information. This can be viewed with the command docker images.
In the case of devicemapper:
  • /var/lib/docker/devicemapper/devicemapper/data stores the images
  • /var/lib/docker/devicemapper/devicemapper/metadata the metadata
  • Note these files are thin provisioned "sparse" files so aren't as big as they seem.
The images are stored in /var/lib/docker/graph/<id>/layer.
Note that images are just diffs from the parent image. The parent ID is stored with the image's metadata /var/lib/docker/graph/<id>/json.
When you docker run an image. AUFS will 'merge' all layers into one usable file system.

-------
* Increase the storage disk for one container which defaults to 10G
* Increase the total data space used by docker on your platform, which defaults to (type ‘docker info’): Data Space Total: 107.4 GB

# docker info
 ...
 Data file: /dev/loop0
 Metadata file: /dev/loop1
 Data Space Total: 107.4 GB
 ...
 Data loop file: /home/docker/devicemapper/devicemapper/data
 Metadata loop file: /home/docker/devicemapper/devicemapper/metadata
Modify docker config file "/etc/sysconfig/docker" option:
OPTIONS='--selinux-enabled=false --storage-opt dm.no_warn_on_loop_devices=true –storage-opt dm.basesize=400G -g /home/docker'
Create 400G data file:
# dd if=/dev/zero of=/home/docker/devicemapper/devicemapper/data bs=1G count=0 seek=400
Docker default ip is 172.17.42.1/16 assign to virtual interface docker0. But docker0 is no ordinary interface. It is a virtual Ethernet bridge that automatically forwards packets between any other network interfaces that are attached to it. This lets containers communicate both with the host machine and with each other. Every time Docker creates a container, it creates a pair of “peer” interfaces that are like opposite ends of a pipe — a packet sent on one will be received on the other. It gives one of the peers to the container to become its eth0interface and keeps the other peer, with a unique name likevethAQI2QT, out in the namespace of the host machine. By binding every veth* interface to the docker0 bridge, Docker creates a virtual subnet shared between the host machine and every Docker container.

Docker is based on so called images. These images are comparable to virtual machine images and contain files, configurations and installed programs. And just like virtual machine images you can start instances of them. A running instance of an image is called container. You can make changes to a container (e.g. delete a file), but these changes will not affect the image. However, you can create a new image from a running container (and all it changes) using docker commit <container-id> <new-image-name>. Export is used to persist a container, and save is used to persist a image. exportwill give you a flat .tar archive containing your container filesystem, all the metadata will be lost, so in case you try to run the container with that image you have remention the CMD and other metdata. (Export-Import creates new Container where as the Save-Load shows time of the original file created.)
docker save and docker load will preserve image metadata (CMD, ENTRYPOINT, etc) and all layers.docker export and docker import don't preserve metadata. This is by design and it's not being changed.
docker export does not export everything about the container — just the filesystem. So, when importing the dump back into a new docker image, additional flags need to be specified to recreate the context.
docker export - saves a container’s running or paused instance to a file
docker save - saves a non-running container image to a file
# sudo docker export <CONTAINER ID> > /home/export.tar
# sudo docker save <image> > /home/save.tar

In rhel 7, create static route file:
# cat /etc/sysconfig/network-scripts/route-em2
172.17.117.0/24 via 172.16.131.1 dev em2
Then the docker interface ip become 172.18.0.1/16

- yum install docker
  # yum install -y docker
  # systemctl disable firewalld && systemctl stop firewalld
  # systemctl enable docker && systemctl start docker
  # docker version
  # docker info
  . to install a CentOS 7 distribution
  # docker pull centos:centos7
  . To display the list of locally available images
  # docker images
  . Show all containers (default shows just running)
  # docker ps -a
  . To test your new image
  # docker run centos:centos7 /bin/ping google.com -c 2
  . create a container
  # mkdir -p /var/www/html
  # restorecon -R /var/www
  # docker run -d -p 8000:8000 --name="python_web" -v /usr/sbin:/usr/sbin -v /usr/bin:/usr/bin -v /usr/lib64:/usr/lib64 -w /var/www/html -v /var/www/html:/var/www/html centos:centos7 /bin/python -m SimpleHTTPServer 8000
  # netstat -tupln | grep 8000
  . stop/remove all docker containers (in bash)
  $ docker stop $(docker ps -a -q)
  $ docker rm $(docker ps -a -q)
  . clean up old containers
  $ docker ps -a | grep 'weeks ago' | awk '{print $1}' | xargs --no-run-if-empty docker rm 
  . copy docker image to another machine
  # docker save -o <save image to path> <image name>
  Or # docker save <image name> > saved.tar
  # docker load -i <path to image tar file>
  Or # docker save <image> | bzip2 | ssh user@host 'bunzip2 | docker load'
  Or # docker save <image> | gzip -9 -c > image.tgz
       # gunzip -c image.tgz | docker load
  . start a stopped container
  # docker start -ai 665b4a1e17b6 # by ID
  # docker start -ai mad_brattain # by name
  . attach to a running container
  # docker attach 665b4a1e17b6
  or to different shell


  # docker exec -i -t 665b4a1e17b6 /bin/bash


  . script to auto upgrade docker images http://stackoverflow.com/questions/26423515/how-to-automatically-update-your-docker-containers-if-base-images-are-updated




  .  to get the number of restarts for container “my-container”
  # docker inspect -f "{{ .RestartCount }}" my-container

  . to get the last time the container was (re)started
 # docker inspect -f "{{ .State.StartedAt }}" my-container
  .wowo
 # docker
  .wowo
 # docker
  .wowo
 # docker
  .wowo
 # docker
  .wowo
 # docker
  .wowo
 # docker