Linux Essentials Certification
Globbing
-
ls ?.txt --- ? stands for one character while * means one or more characters
-
ls [F]*.txt --- list file starting with F
-
ls [F]*.txt --- list file starting with F
-
ls f[igh] --- the first character is f, but the second letter could be each of the characters in the bracket
-
ls [A-Z]*.txt --- list text files that start with a capital letter
Introduction To The Linux Academy
Connecting to Your Server from OSX or Linux
-
user@ip, 123456
-
passwd to change password
Connecting to Your Server from Windows
-
user@ip, port 22
Mastering The Linux Command Line
A Look At Text Editors
-
vi -- :w! means save without closing
-
vi -- :wq! means save and quit
Command Line Keyboard Shortcuts
-
ctrl+a: quickly go to the start of the line
-
ctrl+e: quickly go to the end of the line
-
ctrl+l: clear the screen but the current command
-
ctrl+w: delete one word at a time towards the start of the line
-
ctrl+t: switch the character in front of the cursor and the character cursor is on
-
ctrl+f: move the cursor one character at a time towards the end
-
ctrl+b: move the cursor one character at a time towards the start
-
ctrl+d: delete one character at a time on the cursor
-
ctrl+h: delete the character before the current cursor towards the start
-
ctrl+u: delete everything in front of the cursor towards the start (excluded)
-
ctrl+k: delete everything after the cursor towards the end (included)
-
ctrl+p: take the last command executed
Aliases
-
echo "hello world" >> file.txt append the message to the existing file.txt
-
alias showlog = "tail -f /var/log/file"
-
alias doesn't work everytime you log out
Bash Shell Configuration File & Shell Variables
-
add alias to .bashrc or .bash_profile so that it will work everytime you log back in
-
env: show all the variables set
Setting & Unsetting Environment Variables
-
set: show all the environment variables set in the current bash shell
-
mkdir -p /directory/log: create the directory if it doesn't exist and then create log
-
echo "my messages" > file.txt, redirect the message to the file
-
echo "my messages append" >> file.txt, append the messages to the file
-
export CUSTOM_LOG = "/home/log", set the environment variable
-
unset CUSTOM_LOG , delete the environment variable
-
.bashrc, which is the configuration file will run every time we log in the system
-
cd profile.d and add a customized shell, it will be executed everytime any user logs in
Customizing The Bash Prompt
-
\h: hostname
-
\u: user
-
\t: time
-
\j: show the number of jobs running in the background
-
By modifying PS we could customize the Bash prompt
-
\w: show the entire current working directory
-
\d: show date
-
\W: the last part of the current working directory
Command Line History
-
whoami: show the current user
-
.bash_history: stores all the history of the typed command line
-
ctrl+r: search for the command history
-
history -c: clear all the history
Creating A Simple Bash Script To Automate Commands
-
Take the course "Introduction to bash scripting and linux automation"
-
#!/bin/bash: identifying the interpreter that will run the script
-
chmod +x myscript: give the execution permission of the file
Which and Whereis
-
which: show the whole path of the shell command
-
If the library path has been set in PATH environment variable, then we could just type the command without the full path. e.g. /bin is set in the PATH variable , then we could just type pwd, not /bin/pwd.
-
whereis: show the binary path and also the where is the command in the man page
-
So if one day you type ls and it doesn't work, then use which and whereis to find the full path of it
-
whereis -b iptables: find only the binary files of iptables
Finding Files With Locate
-
touch file1 file2 file3: This command would create three new, empty files named file1, file2 and file3
-
locate: this command will search for the file according to the name in a pre-populated database so it's fast. However this db needs to be updated by a cron job or by manually typing 'updatedb' command
The Powerful Find Command
-
find . -name 'cron*' -- search for all the files and directories start with cron inside the current directory and subdirectories
-
find . -type f -name 'cron*' -- search for only files, no directories
-
find . -type d -name 'cron*' -- search for only directories, no files
-
touch file: this command is used to modify the file's last access time. if the file doesn't exist, then it creates an empty new file
-
find /home -perm 777 -- find all the files with 777 permission
-
find /home -perm 777 -exec chmod 555 {} \; This command will change the permission of the files found. {} means for each of the found file and \; is a good syntax ended
-
find / -mtime +1 -- find all the files modified in the past one day
-
find / -a +1 -- find all the files accessed in the past one day
-
find / -group nameofgroup -- find all the files owned by a group
-
find . -size 1M -- find files of size 1M
-
find . -name 'file*' -exec rm {} \; delete all the files found. {} here means the filename
wc, split, cat, and diff commands
-
cat file1 file2: combines the two files to the output
-
cat file* | wc -l count the line number
-
split -l 2 file1 means split file1 to two files, each of which has two lines
-
diff file1 file2 differences between two files
Streams (stdin, stdout, stderr) and Redirects
-
A sream is what displayed on the linux screen
-
stdin: what you typed in the command line
-
stdout: what output/displayed by linux
-
stderr: error throw by linux
-
cat * > newfile redirect the stdout to the newfile
-
cat * >> newfile append the stdout to the newfile
-
ls filedoesntexist 2> newfile : redirect the stderr to the new file
-
ls filedoesntexist 2>> /dev/null : redirect the error to nothing which means hide the errors
-
cat file1 file2 nofile > mystdoutput 2> mystderr : redirect the output and error to two separate files
-
cat file1 file2 nofile > mystdoutput 2>&1 : also redirect the stderr to the same file
-
set -o noclobber : means you can't override the file using single redirect >
-
set +o noclobber : turn it on
Pipes
-
Pipes allows us to take the output from one command and put it as the input of the other command
-
sort -f : sort while ignore the case
grep, egrep, and fgrep
-
grep ^hello testfile : grep the line starting with hello
-
grep -c ^hello testfile : count all lines starting with hello
-
grep hello$ testfile : grep the line ending with hello
-
grep [hasksxaxs] testfile : grep all the lines containing one or more of the characters in the list
-
grep [a-g] testfile : grep all the lines containing characters between a and g
-
grep -f greppattern testfle : grep the lines in testfile mathing the pattern specified in the greppattern file
-
grep -lr cron /etc : grep all the files recursively that has this pattern in the filename
-
egrep -v 'hello|world' testfile : grep everything that is not hello or world
-
egrep 'hello' testfile | grep -v jeff
-
egrep id for extened regular expressions
-
grep -E means the same thing as egrep
-
grep -F means the same thing as fgrep
-
fgrep means diable all regular expressions, just mathing the keyword as it is
-
fgrep will be faster as it doesn't use regular expression
Cut Command
-
cat passwd : see the contents of the password file
-
cut -f1 -d : passwd --- get the first field cut by ':'
-
-f for field
sed Stream Editor
-
sed 's/parttime/fulltime/' teamfile -- s means substitution. This command means change all parttime to fulltime in the teamfile
-
sed 's/parttime/fulltime/w promotions.txt' teamfile -- s means substitution. This command means change all parttime to fulltime in the teamfile and write all the changes to promotions.txt
-
sed '/fulltime/w fulltime.txt' teamfile write all fulltime lines to fulltime.txt, this will also output the contents of teamfile without any change
-
sed '/fulltime/w fulltime.txt' teamfile /dev/null write all fulltime lines to fulltime.txt without any output
-
sed '0,/parttime/s/parttime/promotion/' teamfile -- the first occurence of parttime will be chnaged to promotion
-
sed 's///' teamfile --- replace all the strings like not with nothing (delete)
tee command
-
tee allow us to read from stdin and write to stdout and files
-
ls | tee mynewfile --- tee command will take the output of the first ls command and write it to mynewfile. The output of the first command will also be displayed as if it is just ls command
-
ls | tee mynewfile mynewfile2 --- could write to multiple files
-
ls | tee -a file --- append the output to the file but not overwrite it. -a for append
-
ls f* | wc -l | tee count.txt --- will display the output results as well. ls f* | wc -l > count.txt will not display the output result
Using Test/Tests On The Linux Command Line
-
test -f file1 && echo "true" --- test if file1 exist, && means if the first part is true, then the next part will be executed
-
test -w file1 && echo "true" --- test if file1 is writable
-
test 1 -gt 2 && echo "true" --- test if 1 is greater than 2
-
test 1 -gt 2 || echo "false" --- || means if the first part is false, then the next part will be executed
-
test 1 -gt 2 && echo "true" || echo "false" --- if true return 'true' if false, return 'false'
-
[] will evaluate the expression inside it
-
[5 -eq 5]; echo $? --- will return 0 if true and return 1 if false
-
["hello" = "hello"]; echo $? --- will return 0 if true and return 1 if false
-
test 5 -eq 5 && echo "yes" || "no"
Lab: Check For Text On A Web Site From The Linux Command Line Using curl & Test
-
curl -s google.com | egrep -ci "301 moved" > /dev/null && ehoc "file has moved" || echo "false" --- could be used to test if the web server is down
-
curl -s google.com | egrep -ci "Internal Server Error" > /dev/null && mail -s "internal server error" chi.zhang@gmail.com
Writing A For Loop On The Command Line
-
for name in `ls`; do echo $name; done; this command will echo the file name one by one from ls command. ` quote will open up a shell, execute the command inside it and put the output to for loop
-
for line in `cat file1`; do echo $line; done;
-
for line in `cat file1`; do echo $line+helloworld; done;
-
for line in `cat file1`; do touch $line; done;
-
for file in `ls /etc`; do echo $file; done;
DevOps Essentials
Continuous Integration and Continuous Deployment
-
Continuous Integration is that people in different modles merge their codes frequently to avoid the possiblily of conflicts or breakings.
-
Continuous Delivery is about how to decide that the current features are valuable enough to be released
Jenkins and Build Automation
Introduction
-
Continuous integration is a development practice that requires developers to integrate code into a shared repository several times per day.
-
Build pipeline is a process by which the software build is broken down in sections: Unit test, Aceeptance test, Packaging, Reporting, Development, Notification
Prerequisites
-
telnet localhost 8080 : find out whether something is running on the port
-
netstat -anp | grep 8080
-
rpm -Uvh jdk-8u25-linux-x64.rpm : Uvh means update if java already exist
-
alternatives --config java : list the installed java versions
-
/etc/rc.d/rc.local : this file will be run everytime for every user when a session is opened including service accounts
Linux Essentials Certification
Globbing
-
ls ?.txt --- ? stands for one character while * means one or more characters
-
ls [F]*.txt --- list file starting with F
-
ls [F]*.txt --- list file starting with F
-
ls f[igh] --- the first characer is f, but the second letter could be each of the characters in the bracket
-
ls [A-Z]*.txt --- list text fils that start with a capital letter
Docker Deep Dive
Creating Our First Image
-
do a system control/chkconfig on on linux to ensure the service start when system reboot
-
docker info - basic information of the current docker installed
-
docker inspect imageName - give all the info of a image in json
-
uname -a : info about the current os system running
-
docker run -i -t ubuntu /bin/bash : open a interaction shell to run commands interactively
-
top : check the prcess running
-
apt-get update downloads the package lists from the repositories and "updates" them to get information on the newest versions of packages and their dependencies. It will do this for all repositories and PPAs
Working With Multiple Images
-
cat /etc/issue : check the linux distribution and kernel info
-
docker run, t means connect to my console, -i means interactive
-
docker search ubuntu : search for ubuntu keywords in docker hub or docker repo
Packaging A Customized Container
-
docker commit -m="Added a ruby module using gem" -a="Linux Academy" a2c67c450ed6 linux academy/sinimage:v1.1 Build a new image
-
docker -t -i linuxacademy/sinimage:v1.1 /bin/bash Create a container from the base imgae we create so that we can interact directly with it
-
docker run -t -i training/sinatra /bin/bash Build from the Dockerfile.
-
Dockerfile : # This is our custom Dockerfile build for sharing FROM ubuntu:latest MAINTAINER Linux Academy RUN apt-get update RUN apt-get install -y ruby ruby-dev
Running Container Commands With Docker
-
docker run -d ubuntu:latest /bin/bash -c "while true; do echo DOCKERMAN; sleep 1; done" : -d means detached the docker to make it run in the background
-
docker stop image_instance_name
-
docker logs image_instance_name: check the log
-
docker logs image_instance_name | wc -l
-
docker pull centos:centos6 will download the centos image with tag centos6
Exposing Our Container With Port Redirects
-
docker run -d -p 8080:80 tutum/apache-php -p means port, redirect local port 8080 to the container port 80 (apache port)
-
docker create -it --name="my_container" ubuntu:latest /bin/bash ---- create a container but not run it.
-
docker restart the container and then use docker attach to go into the running container
Container Snapshots
-
lynx is a brower in linux command line.
-
docker commit container_id centos6:withapache
Attach to a Running Container
-
docker inspect container_name | grep IPAddress | cut -d ":" -f2 | cut -d "\"" -f2
-
docker attach container_name : pompt the shell of the container
-
containers are process oriented, by default it doesn't do anything, we should tell them to do something
Removing Images
-
docker rmi image_id : remove images. Can't delete the image if there is a container depending on it.
-
docker rm container_id : remove container
Directory Structure
-
cd /var/lib/docker
-
init: binary initialization/definition of docker
-
cat repositories-devicemapper
-
cat repositories-devicemapper | python -mjson.tool : -mjson.tool is a python tolol to format the json
-
cd containers, list all the containers directory, it will list the log file and configuration file
-
cd to containers directory and manually delete all the containers by rm -rf *, then sudo service docker restart, then docker will re-read the directory structure
Services That Run on Startup
-
docker run -i -t centos6:withapache /bin/bash, then which service, got /sbin/service, then vi .bashrc, then add a line /sbin/service httpd start
-
The reason docker is not ready to do productinon work is that the shell interaction withh containers is always root (priviliedge)
-
Another way to run a certain service or command is to create a script and then add it to .bashrc
-
!/bin/bash rm -rf /run/httpd/* exec /user/sbin/apachectl -D FOREGROUND
-
chmod 755 /usr/bin/runhttp.sh
-
add "/usr/bin/runttp.sh" to .bashrc
Dockerfile: Tying It Together
-
FROM centos:centos6 ---- Inherit from the base imgae that the repo has or installed locally. First find it locally, if not, find it from docker repo
-
MAINTAINER Chi ---- Have to have contact infor if want to public to docker pub
-
FROM centos:centos6 MAINTAINER Chi RUN yum -y update; yum clean all Run yum -y install httpd Run echo "This is our new Apache Test Site" >> /var/www/html/index.html EXPOSE 80 RUN echo "/sbin/service httpd start" >> /root/.bashrc
-
The whole contents in Dockerfile:
-
FROM centos:centos6 MAINTAINER Chi RUN yum -y update; yum clean all Run yum -y install httpd Run echo "This is our new Apache Test Site" >> /var/www/html/index.html EXPOSE 80 RUN echo "/sbin/service httpd start" >> /root/.bashrc
-
Then docker build -t chi:centos6 . --- . means you can find the Dockerfile right here
-
Each step of the commands in Dockerfile is executed within a new intermidiate container based on the last step
Pushing Images to Docker Hub
-
docker images --- show all the images
-
docker ps -a ---- show all the containers
-
docker build -t ronchy/centos6:beta1 .
-
docker push ronchy/centos6:beta1
Adding External Content
-
FROM ronchy:centos6
-
MAINTAINER ronchy
-
ADD testfile.html /var/www/html/testfile.html --- add the testfile.html to the contents of the image
-
docker build -t test:html .
-
docker run -i -t test:html /bin/bash ---- test:html is the repo/tag
Image Volume Management
-
docker -i -t -v /myapp test:html /bin/bash --- -v means add a volume directory
-
then create myvolume directory in the local server
-
docker run -i -t -v /root/myvolume:/var/volume test:html /bin/bash ---- it will mount the local myvolume directory to the container's /var/volume directory
-
Then if you add a file to local myvolume directory, it will be added to the container's iner directory as well imediately
Advanced Container Network Management
-
ip link add br10 type bridge ---- add bridge br10 to the bridge network interface
-
ip addr add 10.10.100.1/24 dev br10 --- add an address range to the adaptor,
-
ip link set br10 up --- link these together and bring up the network bridge
-
docker.io -d -b br10 & ---- ask docker to use this bridge
-
then if you run docker run -i -t centos:centos6 /bin/bash, docker will be bring up on the up 10.10.100.2. 10.10.100.1 is juet the range/gateway
-
cd /etc/rc.local; this script will be executed after reboot
Interactive Shell Control
-
docker run -i -t --name MYCONTAINER test:html /bin/bash
-
then docker ps to check the container name
-
docker run -i -t -d --name MYCONTAINER test:html /bin/bash
-
docker attach MYCONTAINER
-
docker exec -i -t MYCONTAINER /usr/bin/top ---- This allows to attach to the container and run the command in another prompt. If you exit this prompt, it will exit this container but doesn't kill your original container
-
docker exec -i -t MYCONTAINER /usr/bin/top ---- This allows to attach to the container and run the command in another prompt. If you exit this prompt, it will exit this container but doesn't kill your original container. This allows you to open up a new shell with the running container without affecting the eixting shell
Previous Container Management
-
docker ps -a | grep "7 days" to show the docker status about 7 days ago
-
docker ps -a | grep "7 days" | awk '{print $1}' | xargs docker rm ---- awk, print $1 means print the first column, xargs pass the previous commands result to 'docker rm' command
Container Routing
-
route add -net 172.17.0.0 netmask 255.255.255.0 gw 192.168.1.35 ----Anything goes to 172.17.0.0 will use 192.168.1.35 as gateway
-
then netstat -rn to check the above result
-
172.17.0.0 means the 172.17.0.* range
Sharing Container Resources
-
run -d -i -t -v /data --name DATA1 ronchy:centos6 /bin/bash
-
run -d -i -t --volume-from DATA1 --name DATA2 ronchy:centos6 /bin/bash === the second container mount the volume directories from the first container
Committing a Running Container (Snapshot Images)
-
docker run will first create a container and then run the image inside it
Container Linking and Communication
-
The ENV of mywebserver container will be added to myestcontainer ENV | more
-
link together two containers so that they can securely share information amongst themselves about their IPs, applications and ports all automatically and through environment variables.
-
docker run -i -t --name mytestcontainer --link mywebserver:localweb ronchy;centos6 /bin/bash === This will enable the testcontainer to get the ip and ports and so on of mywebserver container
Taking Control of Ports
-
docker run -i -t -P test:html /bin/bash === dynamically map the internal ports within the container to the local port ranges from 49000 to 49900
-
then the curl http://localhost:49154 (do docker ps to check the assigned port) will get the same result as curl http:172.17.0.23 (ip of docker)
-
docker run -i -t -p 127.0.0.1:5000:80 test:html /bin/bash === map 5000 in local port to 80 inside container
Five Useful Docker CLI Commands
-
docker cp container_name:/etc/yum.conf tmp --- copy the yum.conf file from the container to the local server within the temp directory
-
docker diff container_Name === Show all changes of a contaienr since the base image file. C for change, A for add and D for delete
-
docker events === Real time monitor to see the docker events
-
docker events --since '2016-07-30' show the events from a certain time
-
docker history centos:lates === show the history of a certain image
-
docker -d -i -t --name MyTestContainer1 centos:centos6 /bin/bash; then docker exec -i -t MytestContainer1 /usr/bin/yum -y update ==== This will pas the command to the running container
-
then docker attach MyTestContainer1 will also directly go into this container
More Useful Docker CLI Commands
-
docker info; docker -D info, -D means denug will give more info about docker
-
docker inspect container_name will give json info about this container
-
docker top container_name == show the top command of the container
-
docker stop container_name will take serveral seconds to stop it but docker kill container_name is as doing a kill -9 command
-
docker pause container_name === everything in the container is paused. curl http://ip wil not work.
-
docker unpause container_name will make the container wokr again
-
docker export container_name > container_name.tar === this will build the image to the tar file
-
docker load < container_name.tar or docker load -i container_name.tar; this will read the tar file
-
docker export a container and docker save an image. The exported version is slightly smaller. That is because it is flattened, which means it lost its history and meta-data.
Optimizing Our Dockerfile Builds
-
docker images -t will show all the intermediate containers built
-
instead of doing RUN yum -y upadte; RUN yum -y install httpd; we could do RUN yum -y update && yum -y install httpd && yum -y install openssh-server, all the chained commands should be in just one line not separated lines as before
-
then docker build -i optimized . === optimized is the image name. The chained commands won't ned to commit in between and intermediate containers
Building a Web Farm for Development and Testing (Part Four)
-
yum install nginxl; cd /etc/nginx; cd sites-available; vi default.conf; negix could forward the http request from a ip:host to another
Testing Version Compatibility - Using Tomcat and Java (Part One)
-
alternatives --install /usr/bin/java java /opt/java/bin/java 2 ==== link the /usr/binjava to java application and pass /opt/java/bin/java (the actual path) to the java application.
-
alternatives --config java === complete the java configuration. This gives us oppotunity to choose which java application to run
-
alternatives --set jar /opt/java/bin/java
-
alternatives --set jarc /opt/java/bin/javac
-
alternatives --install /usr/bin/java java /opt/java/bin/java 2 (2 is the priority means the first path will be the primary one if present)
Testing Version Compatibility - Using Tomcat and Java (Part Two)
-
docker commit container_name repo:tag
Testing Version Compatibility - Using Tomcat and Java (Part Three)
-
docker run -i -t --name=tomcatweb7 -v /root/docker/downloads:/root/Downloads -p 8180:8080 -e JAVA_HOME=/opt/java -e JRE_HOME=/opt/java centos6:jdk7tomcat7 /bin/bash
-
We do a -e to pass the environment variables to container as docker doesn't have a way to persist the environment variables across the containers
Dockerfile
# This is our custom Dockerfile build for sharing
FROM ubuntu:latest
MAINTAINER Linux Academy <linuxacademy@email.com>
RUN apt-get update
RUN apt-get install -y ruby ruby-dev
Docker Exercise: Exercise: Installation and Image Setup
-
1 Exercise
-
2 Solution
1. Update your system as appropriate for the distribution you are using. Once updated, for the duration of this exercise, completely disable SELinux on the system and reboot. Once logged in, verify that SELinux is disabled.
[user@linuxacademy:~] sudo yum update (or upgrade)
(Output) Repo updates and packages needing to be updated will be listed here
[user@linuxacademy:~] sudo vim /etc/selinux/config
(Output)...
Find the line: SELINUX=enforcing
Set it to: SELINUX=disabled
Save the file and exit
(Output)...
[user@linuxacademy:~] cat /etc/selinux/config | grep "SELINUX="
2. Using the appropriate package management commands, install the 'docker' package. Once installed, enable the service so that it starts upon reboot. Additionally, start the 'docker' service and verify it is running.
[user@linuxacademy:~] sudo yum -y install docker
(Output) Package downloads and installs here
CentOS 6.x SOLUTION
[user@linuxacademy:~] sudo chkconfig docker
[user@linuxacademy:~] sudo service docker start
CentOS 7.x SOLUTION
[user@linuxacademy:~] sudo systemctl enable docker
[user@linuxacademy:~] sudo systemctl start docker
[user@linuxacademy:~] ps aux | grep docker
(Output)
root 5802 0.0 0.3 346424 12936 ? Ssl 21:02 0:00 /usr/bin/docker -d --selinux-enabled
(Output)
3. Enable the non-root users to run 'docker' commands on the system. Create the appropriate group, add the users you want to have access to 'docker' commands, restart the 'docker' service and verify that non-root users can run basic 'docker' commands.
[user@linuxacademy:~] sudo groupadd docker
[user@linuxacademy:~] vim /etc/group
(Output)...
Find the line that looks like: docker:x:1001:
Add the 'user' user to the end of that line (after the :)
(Output)...
[user@linuxacademy:~] sudo service docker restart (OR sudo systemctl restart docker)
[user@linuxacademy:~] docker images
(Output)
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
(Output)
4. Once 'docker' is installed and non-root users can run commands, use the appropriate 'docker' commands and options to download the latest available image in the public repository for Ubuntu. Once downloaded and installed, verify the image appears in the local base image list.
[user@linuxacademy:~] docker pull ubuntu:latest
(Output) NOTE: Your output may differ if image has been updated
latest: Pulling from docker.io/ubuntu
6071b4945dcf: Pull complete
5bff21ba5409: Pull complete
e5855facec0b: Pull complete
8251da35e7a7: Pull complete
Digest: sha256:1572e29178048ad9ab72e78edd4decc91a3d8a8dea0ca39817efc7cf2d86c6d7
Status: Downloaded newer image for docker.io/ubuntu:latest
(Output)...
[user@linuxacademy:~] docker images
(Output) NOTE: Again, your output may differ slightly
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/ubuntu latest 8251da35e7a7 11 days ago 188.3 MB
(Output)...
5. Start a container based upon the Ubuntu base image downloaded in Step #4. When you start the container, start it connected to the current terminal, in interactive mode, starting the bash shell for you to connect to. You may exit the container at that time.
[user@linuxacademy:~] docker run -it docker.io/ubuntu:latest /bin/bash
(Output) NOTE: Your output will differ based on the container ID assigned
root@7aaf3de3ed4f:/# exit
Docker Exercise: Exercise: Creating Images from Containers
-
1 Exercise
-
2 Solution
1. Using the CentOS 6 base image download, start a container based on that image. Be sure that container starts connected to the current terminal in interactive mode and runs the bash command so you are logged in to the command prompt on the container once it boots.
[user@linuxacademy:~]$ docker run -it centos:centos6 /bin/bash
(Output)
[root@b237d65fd197 /]#
(Output)
2. Once you are sitting at a command prompt on the running container, execute the update command (installing all updates for the container OS).
[root@b237d65fd197 /]# yum -y update (or yum -y upgrade)
(Output)
List of packages needing update and being applied here
(Output)
3. Now that updates are complete, install the Apache Web Server. Once installed, make sure the web server service will start and verify that the container is listening on port 80 (install other software if needed to do so).
[root@b237d65fd197 /]# yum install httpd
(Output)
Installed:
httpd.x86_64 0:2.2.15-45.el6.centos
Dependency Installed:
apr.x86_64 0:1.3.9-5.el6_2 apr-util.x86_64 0:1.3.9-3.el6_0.1 apr-util-ldap.x86_64 0:1.3.9-3.el6_0.1
httpd-tools.x86_64 0:2.2.15-45.el6.centos mailcap.noarch 0:2.1.31-2.el6 redhat-logos.noarch 0:60.0.14-12.el6.centos
Complete!
(Output)
[root@b237d65fd197 /]# yum install telnet
(Output)
Like output above, telnet is installed
(Output)
[root@b237d65fd197 /]# service httpd start
(Output)
httpd start [OK]
(Output)
[root@b237d65fd197 /]# telnet localhost 80
(Output)
Trying 127.0.0.1...
Connected to localhost.localdomain.
Escape character is '^]'.
(Output)
4. Exit the container. Once the container is stopped, execute the appropriate command to list all stopped containers and locate the name and ID of the container you just exited. Make a note of the name and ID.
[root@b237d65fd197 /]# exit
[user@linuxacademy:~]$ docker ps -a
(Output)
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b237d65fd197 centos:6 "/bin/bash" 2 minutes ago Exited (0) 2 minutes ago furious_rosalind
(Output)
5. Using the name or ID of the container, commit the changes you made within it to a new base image called "newcentos:withapache" and verify that it shows when you list the images on your system.
[user@linuxacademy:~]$ docker commit b237d65fd197 newcentos:withapache
(Output)
18bd1fc4d60fa29ff9591f46b86ea0ad7652214d81b4e26343723e81fdbffd8a
(Output)
[user@linuxacademy:~]$ docker images
(Output)
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
newcentos withapache 18bd1fc4d60f 4 seconds ago 480.6 MB
centos 6 a005304e4e74 9 weeks ago 203.1 MB
centos centos6 a005304e4e74 9 weeks ago 203.1 MB
(Output)
Docker Exercise: Exercise: Creating Custom Image from a Dockerfile
-
1 Exercise
-
2 Solution
1. Create a directory called 'custom' and change to it. In this directory, create an empty file called "Dockerfile".
[user@linuxacademy:~]$ mkdir custom
[user@linuxacademy:~]$ cd custom
[user@linuxacademy:custom/]$ touch Dockerfile
2. Edit the "Dockerfile" created in Step #1 above. This configuration file should be written to perform the following actions:
-
Use the base Centos 6 Latest version image from the public repository
-
Identify you and your email address as the author and maintainer of this image
-
Update the base OS after initial import of the image
-
Install the Open-SSH Server
-
Install Apache Web Server
-
Expose ports 22 and 80 to support the services installed
[user@linuxacademy:custom/]$ vi Dockerfile
(Output) NOTE: This is one example of what this file needs to contain, yours may differ slightly
# Dockerfile that modifies centos:centos6 to update, include Apache Web
# Server and OpenSSH Server, exposing the appropriate ports
FROM centos:centos6
MAINTAINER User Name <username@domain.com>
# Update the server OS
RUN yum -y upgrade
# Install Apache Web Server
RUN yum -y install httpd
# Install OpenSSH-Server
RUN yum -y install openssh-server
# Expose the SSH and Web Ports for attachment
EXPOSE 22 80
(Output)
3. Build the custom image from the 'Dockerfile' as created above. Name/tag this new image as "mycustomimg/withservices:v1". Once the image is built, verify the image appears in your list.
[user@linuxacademy:custom/]$ docker build -t mycustomimg/withservices:v1 .
Docker Exercise: Exercise: Managing Containers
-
1 Exercise
-
2 Solution
1. Create a container from the base image for the latest version of Ubuntu available (if you do not have an Ubuntu base image installed locally, pull the latest one down for your local repository). The container should be started in interactive mode attached to the current terminal and running the bash shell. Once running, shut the container down by exiting.
user@linuxacademy:~$ docker pull ubuntu:latest
Pulling repository ubuntu
91e54dfb1179: Download complete
d3a1f33e8a5a: Download complete
c22013c84729: Download complete
d74508fb6632: Download complete
Status: Downloaded newer image for ubuntu:latest
user@linuxacademy:~$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mycustomimg/withservices v1 dcfdd130c812 29 hours ago 506.9 MB
newcentos withapache 18bd1fc4d60f 2 days ago 480.6 MB
ubuntu latest 91e54dfb1179 4 days ago 188.4 MB
ubuntu trusty 91e54dfb1179 4 days ago 188.4 MB
ubuntu trusty-20150814 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04.3 91e54dfb1179 4 days ago 188.4 MB
centos 6 a005304e4e74 9 weeks ago 203.1 MB
centos centos6 a005304e4e74 9 weeks ago 203.1 MB
user@linuxacademy:~$ docker run -it ubuntu:latest /bin/bash
root@a163412a382b:/# exit
exit
2. Run the appropriate Docker command to get the name of the previously run container. Issue the appropriate command to restart the container that you obtained the name of. Do NOT create a new container, restart the one we just used.
user@linuxacademy:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a163412a382b ubuntu:14.04 "/bin/bash" About a minute ago Exited (0) About a minute ago agitated_bohr
b237d65fd197 centos:6 "/bin/bash" 2 days ago Exited (0) 2 days ago furious_rosalind
user@linuxacademy:~$ docker restart agitated_bohr
agitated_bohr
user@linuxacademy:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a163412a382b ubuntu:14.04 "/bin/bash" 2 minutes ago Up 16 seconds agitated_bohr
3. Stop the container. Remove that container from the system completely using the appropriate command.
user@linuxacademy:~$ docker stop agitated_bohr
agitated_bohr
user@linuxacademy:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
user@linuxacademy:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a163412a382b ubuntu:14.04 "/bin/bash" 3 minutes ago Exited (0) 5 seconds ago agitated_bohr
b237d65fd197 centos:6 "/bin/bash" 2 days ago Exited (0) 2 days ago furious_rosalind
user@linuxacademy:~$ docker rm agitated_bohr
agitated_bohr
user@linuxacademy:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b237d65fd197 centos:6 "/bin/bash" 2 days ago Exited (0) 2 days ago furious_rosalind
4. Create (not run) a container called "my_container", create it with parameters that will allow it to run interactively and attached to the local console running the bash shell. Verify that the container is not running.
user@linuxacademy:~$ docker create -it --name="my_container" ubuntu:latest /bin/bash
a8eccaa97e322ff640bb9f7071f191dc9a514afb324af28269ffbb7ae754666f
user@linuxacademy:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8eccaa97e32 ubuntu:14.04 "/bin/bash" 4 seconds ago my_container
b237d65fd197 centos:6 "/bin/bash" 2 days ago Exited (0) 2 days ago furious_rosalind
5. Start the container and again, verify the container is running. Run the appropriate command to attach your session to the running container so you are logged into the shell.
user@linuxacademy:~$ docker start my_container
my_container
user@linuxacademy:~$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8eccaa97e32 ubuntu:14.04 "/bin/bash" 30 seconds ago Up 2 seconds my_container
user@linuxacademy:~$ docker attach my_container
root@a8eccaa97e32:/#
root@a8eccaa97e32:/# exit
Docker Exercise: Exercise: Base Image Maintenance and Cleanup
-
1 Exercise
-
2 Solution
1. List all currently install Docker images. If you do not have at least three Docker base images at this point, please pull down other Docker images and/or follow the other exercises in this tutorial.
user@linuxacademy:~$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mycustomimg/withservices v1 dcfdd130c812 30 hours ago 506.9 MB
newcentos withapache 18bd1fc4d60f 2 days ago 480.6 MB
ubuntu latest 91e54dfb1179 4 days ago 188.4 MB
ubuntu trusty 91e54dfb1179 4 days ago 188.4 MB
ubuntu trusty-20150814 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04.3 91e54dfb1179 4 days ago 188.4 MB
centos 6 a005304e4e74 9 weeks ago 203.1 MB
centos centos6 a005304e4e74 9 weeks ago 203.1 MB
2. Execute the command to remove a base image that you have previously created a container from and note the resulting message.
user@linuxacademy:~$ docker rmi centos:6
Error response from daemon: Conflict, cannot delete a005304e4e74 because the container bad607059560 is using it, use -f to force
FATA[0000] Error: failed to remove one or more images
3. Run the appropriate command to remove the container that Step #2 indicated is preventing the deletion of that base image.
user@linuxacademy:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bad607059560 centos:6 "/bin/bash" 2 minutes ago Exited (0) About a minute ago insane_tesla
a8eccaa97e32 ubuntu:14.04 "/bin/bash" 29 minutes ago Exited (0) 28 minutes ago my_container
b237d65fd197 centos:6 "/bin/bash" 2 days ago Exited (0) 2 days ago furious_rosalind
user@linuxacademy:~$ docker rm insane_tesla
insane_tesla
user@linuxacademy:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8eccaa97e32 ubuntu:14.04 "/bin/bash" 29 minutes ago Exited (0) 28 minutes ago my_container
b237d65fd197 centos:6 "/bin/bash" 2 days ago Exited (0) 2 days ago furious_rosalind
4. List all previously run containers and remove all of them one at a time. Verify that the command to list stopped containers shows nothing before continuing.
user@linuxacademy:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8eccaa97e32 ubuntu:14.04 "/bin/bash" 30 minutes ago Exited (0) 29 minutes ago my_container
b237d65fd197 centos:6 "/bin/bash" 2 days ago Exited (0) 2 days ago furious_rosalind
user@linuxacademy:~$ docker rm my_container && docker rm furious_rosalind
my_container
furious_rosalind
user@linuxacademy:~$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5. Rerun the command executed in Step #2 and then list the base images on your system.
user@linuxacademy:~$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mycustomimg/withservices v1 dcfdd130c812 30 hours ago 506.9 MB
newcentos withapache 18bd1fc4d60f 2 days ago 480.6 MB
ubuntu 14.04 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04.3 91e54dfb1179 4 days ago 188.4 MB
ubuntu latest 91e54dfb1179 4 days ago 188.4 MB
ubuntu trusty 91e54dfb1179 4 days ago 188.4 MB
ubuntu trusty-20150814 91e54dfb1179 4 days ago 188.4 MB
centos 6 a005304e4e74 9 weeks ago 203.1 MB
user@linuxacademy:~$ docker rmi centos:6
Untagged: centos:6
user@linuxacademy:~$ docker images
Docker Exercise: Exercise: Exposing Container Ports to the Host
-
1 Exercise
-
2 Solution
1. Create a container from the 'centos:6' base image on your system. This container does not need to be name but should be run in daemon mode, interactive and connected to the current terminal. Finally, it should start the bash shell on start up.
[user@linuxacademy ~]$ docker run -itd docker.io/centos:6 /bin/bash
99f87625ff34a5a25af8edd7e95ad9b6a4bc70db63c2ac6e0850dd4cfae58cef
[user@linuxacademy ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99f87625ff34 docker.io/centos:6 "/bin/bash" 3 seconds ago Up 2 seconds elegant_bohr
[user@linuxacademy ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99f87625ff34 docker.io/centos:6 "/bin/bash" 5 seconds ago Up 5 seconds elegant_bohr
2. Using the appropriate Docker inspection command, find the IP address and name for the running container. Once you have the IP, ping the IP to be sure it is running. Finally, attach to the running container so you are logged into the shell.
[user@linuxacademy ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99f87625ff34 docker.io/centos:6 "/bin/bash" 7 minutes ago Up 7 minutes elegant_bohr
[user@linuxacademy]$ docker inspect elegant_bohr | grep IP
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null
[user@linuxacademy ~]$ ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.069 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.096 ms
^C
--- 172.17.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.069/0.082/0.096/0.016 ms
[user@linuxacademy ~]$ docker attach elegant_bohr
[root@99f87625ff34 /]#
3. From within the container, install the Open-SSH server and make sure the service is running. From another terminal, try to log into the container over SSH by IP and note the result.
[root@99f87625ff34 /]# yum install openssh-server
... Lots of Output Here
Installed:
openssh-server.x86_64 0:5.3p1-112.el6_7
Dependency Installed:
fipscheck.x86_64 0:1.2.0-7.el6 fipscheck-lib.x86_64 0:1.2.0-7.el6 openssh.x86_64 0:5.3p1-112.el6_7
tcp_wrappers-libs.x86_64 0:7.6-57.el6
Complete!
[root@99f87625ff34 /]# service sshd start
Generating SSH2 RSA host key: [ OK ]
Generating SSH1 RSA host key: [ OK ]
Generating SSH2 DSA host key: [ OK ]
Starting sshd:
(Different Terminal)
[user@linuxacademy ~]$ ssh test@172.17.0.2
ssh: connect to host 172.17.0.2 port 22: Connection refused
4. Exit and stop the container. Remove the container from the list of previously run containers once you obtain the name from the appropriate Docker command.
[user@linuxacademy ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99f87625ff34 docker.io/centos:6 "/bin/bash" About an hour ago Exited (0) 4 seconds ago elegant_bohr
8ef073d5c7f4 docker.io/centos:6 "/bin/bash" About an hour ago Exited (0) About an hour ago silly_poincare
[user@linuxacademy ~]$ docker rm elegant_bohr
elegant_bohr
[user@linuxacademy ~]$ docker rm silly_poincare
silly_poincare
[user@linuxacademy ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/ubuntu latest 91e54dfb1179 4 days ago 188.3 MB
docker.io/centos 6 a005304e4e74 9 weeks ago 203.1 MB
[user@linuxacademy ~]$
5. Create another container, name this container 'test_ssh'. When creating the container, it should be run in interactive mode and attached to the current terminal running the bash shell. Finally, expose port 22 on the container to port 8022 on the host system. Once logged in, install the Open-SSH server and make sure the service is running. Find the IP address of the container and note it.
[user@linuxacademy ~]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[user@linuxacademy ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
99f87625ff34 docker.io/centos:6 "/bin/bash" About an hour ago Exited (0) 4 seconds ago elegant_bohr
8ef073d5c7f4 docker.io/centos:6 "/bin/bash" About an hour ago Exited (0) About an hour ago silly_poincare
[user@linuxacademy ~]$ docker rm elegant_bohr
elegant_bohr
[user@linuxacademy ~]$ docker rm silly_poincare
silly_poincare
[user@linuxacademy ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/ubuntu latest 91e54dfb1179 4 days ago 188.3 MB
docker.io/centos 6 a005304e4e74 9 weeks ago 203.1 MB
[user@linuxacademy ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/ubuntu latest 91e54dfb1179 4 days ago 188.3 MB
docker.io/centos 6 a005304e4e74 9 weeks ago 203.1 MB
[user@linuxacademy ~]$ docker run -it --name="test_ssh" -p 8022:22 docker.io/centos:6 /bin/bash
Usage of loopback devices is strongly discouraged for production use. Either use `--storage-opt dm.thinpooldev` or use `--storage-opt dm.no_warn_on_loop_devices=true` to suppress this warning.
[root@de1119934beb /]# yum install openssh-server
Loaded plugins: fastestmirror
Setting up Install Process
base | 3.7 kB 00:00
base/primary_db | 4.6 MB 00:07
extras | 3.4 kB 00:00
extras/primary_db | 27 kB 00:00
updates | 3.4 kB 00:00
updates/primary_db | 1.3 MB 00:01
Resolving Dependencies
--> Running transaction check
---> Package openssh-server.x86_64 0:5.3p1-112.el6_7 will be installed
--> Processing Dependency: openssh = 5.3p1-112.el6_7 for package: openssh-server-5.3p1-112.el6_7.x86_64
--> Processing Dependency: libwrap.so.0()(64bit) for package: openssh-server-5.3p1-112.el6_7.x86_64
--> Processing Dependency: libfipscheck.so.1()(64bit) for package: openssh-server-5.3p1-112.el6_7.x86_64
--> Running transaction check
---> Package fipscheck-lib.x86_64 0:1.2.0-7.el6 will be installed
--> Processing Dependency: /usr/bin/fipscheck for package: fipscheck-lib-1.2.0-7.el6.x86_64
---> Package openssh.x86_64 0:5.3p1-112.el6_7 will be installed
---> Package tcp_wrappers-libs.x86_64 0:7.6-57.el6 will be installed
--> Running transaction check
---> Package fipscheck.x86_64 0:1.2.0-7.el6 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
===============================================================================================================================
Package Arch Version Repository Size
===============================================================================================================================
Installing:
openssh-server x86_64 5.3p1-112.el6_7 updates 324 k
Installing for dependencies:
fipscheck x86_64 1.2.0-7.el6 base 14 k
fipscheck-lib x86_64 1.2.0-7.el6 base 8.3 k
openssh x86_64 5.3p1-112.el6_7 updates 274 k
tcp_wrappers-libs x86_64 7.6-57.el6 base 62 k
Transaction Summary
===============================================================================================================================
Install 5 Package(s)
Total download size: 682 k
Installed size: 1.6 M
Is this ok [y/N]: y
Downloading Packages:
(1/5): fipscheck-1.2.0-7.el6.x86_64.rpm | 14 kB 00:00
(2/5): fipscheck-lib-1.2.0-7.el6.x86_64.rpm | 8.3 kB 00:00
(3/5): openssh-5.3p1-112.el6_7.x86_64.rpm | 274 kB 00:00
(4/5): openssh-server-5.3p1-112.el6_7.x86_64.rpm | 324 kB 00:00
(5/5): tcp_wrappers-libs-7.6-57.el6.x86_64.rpm | 62 kB 00:00
-------------------------------------------------------------------------------------------------------------------------------
Total 306 kB/s | 682 kB 00:02
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>
Package: centos-release-6-6.el6.centos.12.2.x86_64 (@CentOS/$releasever)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Is this ok [y/N]: y
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Warning: RPMDB altered outside of yum.
Installing : fipscheck-1.2.0-7.el6.x86_64 1/5
Installing : fipscheck-lib-1.2.0-7.el6.x86_64 2/5
Installing : openssh-5.3p1-112.el6_7.x86_64 3/5
Installing : tcp_wrappers-libs-7.6-57.el6.x86_64 4/5
Installing : openssh-server-5.3p1-112.el6_7.x86_64 5/5
Verifying : tcp_wrappers-libs-7.6-57.el6.x86_64 1/5
Verifying : fipscheck-lib-1.2.0-7.el6.x86_64 2/5
Verifying : fipscheck-1.2.0-7.el6.x86_64 3/5
Verifying : openssh-5.3p1-112.el6_7.x86_64 4/5
Verifying : openssh-server-5.3p1-112.el6_7.x86_64 5/5
Installed:
openssh-server.x86_64 0:5.3p1-112.el6_7
Dependency Installed:
fipscheck.x86_64 0:1.2.0-7.el6 fipscheck-lib.x86_64 0:1.2.0-7.el6 openssh.x86_64 0:5.3p1-112.el6_7
tcp_wrappers-libs.x86_64 0:7.6-57.el6
Complete!
[root@de1119934beb /]# service sshd start
Generating SSH2 RSA host key: [ OK ]
Generating SSH1 RSA host key: [ OK ]
Generating SSH2 DSA host key: [ OK ]
Starting sshd: [ OK ]
[root@de1119934beb /]# ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:AC:11:00:03
inet addr:172.17.0.3 Bcast:0.0.0.0 Mask:255.255.0.0
inet6 addr: fe80::42:acff:fe11:3/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:3944 errors:0 dropped:0 overruns:0 frame:0
TX packets:2104 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:7151212 (6.8 MiB) TX bytes:116622 (113.8 KiB)
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)
[root@de1119934beb /]#
6. Install the 'sudo' utility. Add a user called 'test' and set a password for that user. Add the 'test' user to the 'sudoers' file. From another terminal window, attempt to log into the container via SSH on port 8022 as the 'test' user and confirm access.
[root@de1119934beb /]# yum install sudo
Loaded plugins: fastestmirror
Setting up Install Process
Determining fastest mirrors
* base: repos.dfw.quadranet.com
* extras: centos.mirror.lstn.net
* updates: mirror.steadfast.net
Resolving Dependencies
--> Running transaction check
---> Package sudo.x86_64 0:1.8.6p3-20.el6_7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
===============================================================================================================================
Package Arch Version Repository Size
===============================================================================================================================
Installing:
sudo x86_64 1.8.6p3-20.el6_7 updates 707 k
Transaction Summary
===============================================================================================================================
Install 1 Package(s)
Total download size: 707 k
Installed size: 2.4 M
Is this ok [y/N]: y
Downloading Packages:
sudo-1.8.6p3-20.el6_7.x86_64.rpm | 707 kB 00:02
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : sudo-1.8.6p3-20.el6_7.x86_64 1/1
Verifying : sudo-1.8.6p3-20.el6_7.x86_64 1/1
Installed:
sudo.x86_64 0:1.8.6p3-20.el6_7
Complete!
[root@de1119934beb /]# adduser test
[root@de1119934beb /]# passwd test
Changing password for user test.
New password:
BAD PASSWORD: it is based on a dictionary word
Retype new password:
passwd: all authentication tokens updated successfully.
[root@de1119934beb /]#
(Other Terminal Window)
[user@linuxacademy ~]$ ssh test@172.17.0.3
The authenticity of host '172.17.0.3 (172.17.0.3)' can't be established.
RSA key fingerprint is e8:5e:28:d8:64:1f:81:3a:d9:4c:2c:0c:8e:a1:27:b7.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.17.0.3' (RSA) to the list of known hosts.
test@172.17.0.3's password:
[test@de1119934beb ~]$
Docker Exercise: Exercise: Advanced Container Creation at the Command Line
-
1 Exercise
-
2 Solution
1. Using the Docker base image for Ubuntu, create a container with the following characteristics:
- Interactive
- Attached to Terminal
- Using Google Public DNS
- Named 'mycontainer1'
[user@linuxacademy docker]$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
docker.io/ubuntu latest 91e54dfb1179 5 days ago 188.3 MB
docker.io/centos 6 a005304e4e74 9 weeks ago 203.1 MB
[user@linuxacademy docker]$ docker run -it --dns=8.8.8.8 --name="mycontainer1" docker.io/ubuntu:latest /bin/bash
root@6330006f7289:/# cat /etc/resolv.conf
nameserver 8.8.8.8
2. Exit the container from Step #1. Using the Docker base image for Ubuntu, create a container with the following characteristics:
- Interactive
- Attached to Terminal
- Using Google Public DNS
- Using Domain Search "mydomain.local"
- Named 'mycontainer2'
[user@linuxacademy docker]$ docker run -it --dns=8.8.8.8 --dns-search="mydomain.local" --name="mycontainer2" docker.io/ubuntu:latest /bin/bash
root@2879176e6c81:/# cat /etc/resolv.conf
nameserver 8.8.8.8
search mydomain.local
3. Exit the container from Step #2. Using the Docker base image for Ubuntu, create a container with the following characteristics:
- Interactive
- Attached to Terminal
- Using Google Public DNS
- Using Domain Search "mydomain.local"
- Create a mount called '/local_vol'
- Create a mount called '/remote_vol' that mounts the file system in /home/user
- Named 'mycontainer3'
[user@linuxacademy docker]$ docker run -it --dns=8.8.8.8 --dns-search="mydomain.local" --name="mycontainer3" -v /local_vol -v /home/tcox/docker/mydata:/remote_vol docker.io/ubuntu:latest /bin/bash
root@c5e3e6599556:/# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/docker-8:2-203558447-c5e3e65995567b3249f537843d4ff39644925c9265bbd48cd623b6e3564eef52 9.8G 245M 9.0G 3% /
tmpfs 2.0G 0 2.0G 0% /dev
shm 64M 0 64M 0% /dev/shm
/dev/sda2 36G 4.3G 32G 12% /local_vol
tmpfs 2.0G 0 2.0G 0% /run/secrets
tmpfs 2.0G 0 2.0G 0% /proc/kcore
tmpfs 2.0G 0 2.0G 0% /proc/timer_stats
root@c5e3e6599556:/# cat /etc/resolv.conf
nameserver 8.8.8.8
search mydomain.local
root@c5e3e6599556:/# cd /local_vol/
root@c5e3e6599556:/local_vol# cd /remote_vol/
root@c5e3e6599556:/remote_vol#
4. Exit the container from Step #3. List all the containers. List all characteristics inspected from 'mycontainer2' and then remove and verify removal of all containers.
[user@linuxacademy docker]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c5e3e6599556 docker.io/ubuntu:latest "/bin/bash" 2 minutes ago Exited (0) 3 seconds ago mycontainer3
2879176e6c81 docker.io/ubuntu:latest "/bin/bash" 4 minutes ago Exited (0) 3 minutes ago mycontainer2
6330006f7289 docker.io/ubuntu:latest "/bin/bash" 7 minutes ago Exited (0) 5 minutes ago mycontainer1
[user@linuxacademy docker]$ docker inspect mycontainer1
(NOTE: SOMETHING SIMILAR FOR EACH CONTAINER - RUN THE ABOVE COMMAND FOR EACH NAME)
[
{
"Id": "6330006f72899510254d23f845c4507d604773d2fcf2bffb77f44da1330208c1",
"Created": "2015-08-25T21:05:43.135824241Z",
"Path": "/bin/bash",
"Args": [],
"State": {
"Running": false,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 0,
"ExitCode": 0,
"Error": "",
"StartedAt": "2015-08-25T21:05:44.409339189Z",
"FinishedAt": "2015-08-25T21:07:32.103884307Z"
},
"Image": "91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c",
"NetworkSettings": {
"Bridge": "",
"EndpointID": "",
"Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"HairpinMode": false,
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"MacAddress": "",
"NetworkID": "",
"PortMapping": null,
"Ports": null,
"SandboxKey": "",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null
},
"ResolvConfPath": "/var/lib/docker/containers/6330006f72899510254d23f845c4507d604773d2fcf2bffb77f44da1330208c1/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/6330006f72899510254d23f845c4507d604773d2fcf2bffb77f44da1330208c1/hostname",
"HostsPath": "/var/lib/docker/containers/6330006f72899510254d23f845c4507d604773d2fcf2bffb77f44da1330208c1/hosts",
"LogPath": "/var/lib/docker/containers/6330006f72899510254d23f845c4507d604773d2fcf2bffb77f44da1330208c1/6330006f72899510254d23f845c4507d604773d2fcf2bffb77f44da1330208c1-json.log",
"Name": "/mycontainer1",
"RestartCount": 0,
"Driver": "devicemapper",
"ExecDriver": "native-0.2",
"MountLabel": "",
"ProcessLabel": "",
"Volumes": {},
"VolumesRW": {},
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LxcConf": [],
"Memory": 0,
"MemorySwap": 0,
"CpuShares": 0,
"CpuPeriod": 0,
"CpusetCpus": "",
"CpusetMems": "",
"CpuQuota": 0,
"BlkioWeight": 0,
"OomKillDisable": false,
"Privileged": false,
"PortBindings": {},
"Links": null,
"PublishAllPorts": false,
"Dns": [
"8.8.8.8"
],
"DnsSearch": null,
"ExtraHosts": null,
"VolumesFrom": null,
"Devices": [],
"NetworkMode": "bridge",
"IpcMode": "",
"PidMode": "",
"UTSMode": "",
"CapAdd": null,
"CapDrop": null,
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"SecurityOpt": null,
"ReadonlyRootfs": false,
"Ulimits": null,
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"CgroupParent": ""
},
"Config": {
"Hostname": "6330006f7289",
"Domainname": "",
"User": "",
"AttachStdin": true,
"AttachStdout": true,
"AttachStderr": true,
"PortSpecs": null,
"ExposedPorts": null,
"Tty": true,
"OpenStdin": true,
"StdinOnce": true,
"Env": null,
"Cmd": [
"/bin/bash"
],
"Image": "docker.io/ubuntu:latest",
"Volumes": null,
"VolumeDriver": "",
"WorkingDir": "",
"Entrypoint": null,
"NetworkDisabled": false,
"MacAddress": "",
"OnBuild": null,
"Labels": {},
"Init": ""
}
}
]
[user@linuxacademy docker]$ docker rm mycontainer1
mycontainer1
[user@linuxacademy docker]$ docker rm mycontainer2
mycontainer2
[user@linuxacademy docker]$ docker rm mycontainer3
mycontainer3
[user@linuxacademy docker]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Docker Exercise: Exercise: Create a Dockerized Basic Web Server
-
1 Exercise
-
2 Solution
1. List the base images on the system. Choose a base image for Ubuntu and create a container from that image. This container should be named "basic_web" and should be interactive, attached to the current console and run the bash prompt.
user@linuxacademy:~$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
mycustomimg/withservices v1 dcfdd130c812 31 hours ago 506.9 MB
newcentos withapache 18bd1fc4d60f 2 days ago 480.6 MB
ubuntu trusty-20150814 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04.3 91e54dfb1179 4 days ago 188.4 MB
ubuntu latest 91e54dfb1179 4 days ago 188.4 MB
ubuntu trusty 91e54dfb1179 4 days ago 188.4 MB
user@linuxacademy:~$ docker run -it --name="basic_web" ubuntu:latest /bin/bash
root@528b8c33ab7a:/#
2. Once you are logged into the container at the prompt, install all updates. After updates are installed, install the Apache Web Server and verify that it is listening on Port 80.
root@528b8c33ab7a:/# apt-get update && apt-get upgrade && apt-get install apache2
(OUTPUT) NOTE: sample of the end of the output
...
3Enabling module setenvif.
Enabling module filter.
Enabling module deflate.
Enabling module status.
Enabling conf charset.
Enabling conf localized-error-pages.
Enabling conf other-vhosts-access-log.
Enabling conf security.
Enabling conf serve-cgi-bin.
Enabling site 000-default.
invoke-rc.d: policy-rc.d denied execution of start.
Setting up ssl-cert (1.0.33) ...
Processing triggers for libc-bin (2.19-0ubuntu6.6) ...
Processing triggers for sgml-base (1.26+nmu4ubuntu1) ...
Processing triggers for ureadahead (0.100.0-16) ...
root@528b8c33ab7a:/#
root@528b8c33ab7a:/# apt-get install telnet
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
telnet
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 67.1 kB of archives.
After this operation, 167 kB of additional disk space will be used.
Get:1 http://archive.ubuntu.com/ubuntu/ trusty/main telnet amd64 0.17-36build2 [67.1 kB]
Fetched 67.1 kB in 0s (89.7 kB/s)
Selecting previously unselected package telnet.
(Reading database ... 12458 files and directories currently installed.)
Preparing to unpack .../telnet_0.17-36build2_amd64.deb ...
Unpacking telnet (0.17-36build2) ...
Setting up telnet (0.17-36build2) ...
update-alternatives: using /usr/bin/telnet.netkit to provide /usr/bin/telnet (telnet) in auto mode
root@528b8c33ab7a:/# telnet localhost 80
Trying ::1...
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
root@528b8c33ab7a:/# service apache2 start
* Starting web server apache2 AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.13. Set the 'ServerName' directive globally to suppress this message
*
root@528b8c33ab7a:/# telnet localhost 80
Trying ::1...
Connected to localhost.
Escape character is '^]'.
helo
501 Not Implemented
Not Implemented
helo to /index.html not supported.
Apache/2.4.7 (Ubuntu) Server at 172.17.0.13 Port 80
Connection closed by foreign host.
root@528b8c33ab7a:/#
3. Using the root account profile file in the root home directory, add the command to start the web server whenever a bash session is started.
root@528b8c33ab7a:~# vi .bashrc
NOTE: Add the line "service apache2 start" to the /root/.bashrc file at the very END
4. Stop the container. Once stopped, commit the container as a base image called "centos:baseweb".
root@528b8c33ab7a:~# exit
tcox@ubuntuvideo:~$ docker commit basic_web centos:baseweb
e9c87aeba30b82e66edb7143b89c10b801b866002f0659d0fd78ba5b48a82e8e
tcox@ubuntuvideo:~$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos baseweb e9c87aeba30b 3 seconds ago 224.2 MB
mycustomimg/withservices v1 dcfdd130c812 31 hours ago 506.9 MB
newcentos withapache 18bd1fc4d60f 2 days ago 480.6 MB
ubuntu trusty 91e54dfb1179 4 days ago 188.4 MB
ubuntu trusty-20150814 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04 91e54dfb1179 4 days ago 188.4 MB
ubuntu 14.04.3 91e54dfb1179 4 days ago 188.4 MB
ubuntu latest 91e54dfb1179 4 days ago 188.4 MB
5. Create a container based on the new "centos:baseweb" image called "test_container". It should run interactively, attached to the console and starting a bash prompt. Once logged into the container, verify that the Apache service is running and port 80 is listening. Exit the container.
user@linuxacademy:~$ docker run -it --name="test_container" centos:baseweb /bin/bash
* Starting web server apache2 AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.14. Set the 'ServerName' directive globally to suppress this message
*
root@b830f2ecb2ca:/# telnet localhost 80
Trying ::1...
Connected to localhost.
Escape character is '^]'.
helo
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>501 Not Implemented</title>
</head><body>
<h1>Not Implemented</h1>
<p>helo to /index.html not supported.<br />
</p>
<hr>
<address>Apache/2.4.7 (Ubuntu) Server at 172.17.0.14 Port 80</address>
</body></html>
Connection closed by foreign host.
root@b830f2ecb2ca:/# exit