Docker学習 (メモ)

## Getting a shell inside the Containers
- docker container run -it → start new container interactively
    -  -t, --tty : Allocate a pseudo-TTY (Simulates a real terminal, like what SSH does)
    -  -i, --interactive : Keep STDIN open even if not attached (Keep session open to receive terminal input)
- docker container exec -it → run additional command in existing container


```bash:getting-shell-inside-new-container-nginx
# bash shell : if run with -it, it will give you a terminal inside the running container
vagrant@bionic64:~ % docker container run -it --name proxy nginx bash
root@f70483b16118:/# exit
exit

# proxy container isn't running anymore so it didn't appear
vagrant@bionic64:~ % docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
67d7abe5ee19        mysql               "docker-entrypoint.s…"   6 hours ago         Up 6 hours          3306/tcp, 33060/tcp   mysql
2f7b9d2bb79f        nginx               "nginx -g 'daemon of…"   6 hours ago         Up 6 hours          80/tcp                nginx

# but on the list of all running container it appear. The default command for nginx container
# is to run the nginx program itself (nginx -g 'daemon...), but i changed the default command
# to be bash (shell), and when exit the shell the container will stop
vagrant@bionic64:~ % docker container ls -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                          PORTS                 NAMES
f70483b16118        nginx               "bash"                   3 minutes ago       Exited (0) About a minute ago                         proxy
67d7abe5ee19        mysql               "docker-entrypoint.s…"   6 hours ago         Up 6 hours                      3306/tcp, 33060/tcp   mysql
2f7b9d2bb79f        nginx               "nginx -g 'daemon of…"   6 hours ago         Up 6 hours                      80/tcp                nginx
```

```bash:getting-shell-inside-new-container-ubuntu
vagrant@bionic64:~ % docker container run -it --name ubuntu ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
d51af753c3d3: Pull complete
fc878cd0a91c: Pull complete
6154df8ff988: Pull complete
fee5db0ff82f: Pull complete
Digest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7
Status: Downloaded newer image for ubuntu:latest
root@d1dfcd290a4e:/#

# Update package list
root@d1dfcd290a4e:/# apt-get install -y curl sudo vim

# exit from Ubuntu Container
root@d1dfcd290a4e:/# exit
exit

# Rerun Ubuntu Container again
vagrant@bionic64:~ % docker container start -ai ubuntu
root@d1dfcd290a4e:/#
```

```bash:getting-shell-inside-existing-container-mysql
# List all runing docker containers
vagrant@bionic64:~ % docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
67d7abe5ee19        mysql               "docker-entrypoint.s…"   25 hours ago        Up 25 hours         3306/tcp, 33060/tcp   mysql
2f7b9d2bb79f        nginx               "nginx -g 'daemon of…"   25 hours ago        Up 25 hours         80/tcp                nginx

# Run bash on mysql container
vagrant@bionic64:~ % docker container exec -it mysql bash
root@67d7abe5ee19:/#

# View process inside mysql container
root@67d7abe5ee19:/# apt-get update && apt-get install -y procps
Get:1 http://deb.debian.org/debian buster InRelease [122 kB]
Get:2 http://repo.mysql.com/apt/debian buster InRelease [21.5 kB]
....
Processing triggers for libc-bin (2.28-10) ...

root@67d7abe5ee19:/# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
mysql        1  0.8 10.0 1807908 407732 ?      Ssl  Apr24   7:35 mysqld
root       197  0.1  0.0   3868  3236 pts/0    Ss   02:10   0:00 bash
root       602  0.0  0.0   7640  2712 pts/0    R+   02:13   0:00 ps aux

# When exit from mysql container bash, the container still running because the docker container exec　actually 
# runs an additional process on an existing running container, it's not going to affect the root process for the 
# mysql daemon.
vagrant@bionic64:~ % docker container ls
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                 NAMES
67d7abe5ee19        mysql               "docker-entrypoint.s…"   25 hours ago        Up 25 hours         3306/tcp, 33060/tcp   mysql
2f7b9d2bb79f        nginx               "nginx -g 'daemon of…"   25 hours ago        Up 25 hours         80/tcp                nginx
```

## Alpine
Alpine is another distributions of Linux, a small security-focuesed, actually 5MB in size
https://www.alpinelinux.org/

```bash:getting-shell-inside-alpine-linux

# pull alpine image from dockerhub
vagrant@bionic64:~ % docker pull alpine

# get into alpine container (alpine is so small that it didn't have bash inside it
vagrant@bionic64:~ % docker container run -it alpine sh
/ #
```
## Docker Network
- Each container connected to a private virtual network
- Each virtual network routes through NAT firewall on host IP
- All containers on a virtual network can talk to each other without -p
- Attach containers to more then one virtual network or none
- Skip virtual networks and use host IP (--net=host)
- Use different Docker network drivers to gain new abilities
- Best practise is to create a new virtual network for each app:
    - Network "my_web_app" for mysql and php/apache containers
    - Network "my_api" for mongo and nodejs containers

```bash:docker-network
# show all the network that have been created
# --network bridge : default docker virtual network, which is nat'ed behind the host IP
# --network host : special network that skips the virtual networking of docker and attaches the container directly to the host interface (it gains performance by skipping virtual networks but sacrifices security of container model)
# --network none : remove eth0 and only leaves you with localhost interface in container
vagrant@bionic64:~ % docker network ls
NETWORK ID          NAME                      DRIVER              SCOPE
8a0c0904042b        bridge                    bridge              local
82c89c6d7ced        host                      host                local
065b00bd675e        none                      null                local
3ac2975fe4ea        operation_report          bridge              local
969195599b15        operationreport_default   bridge              local

# lists the containers attached to the bridge network
# 172.17, is default subnet network for any docker host
vagrant@bionic64:~ % docker network inspect bridge

# create a docker network
# docker network create : spawns a new virtual network for you to attach containers to
vagrant@bionic64:~ % docker network create my_app_network
9de8bdfbf0b5cafa7fc1096831ec721cdc7b254877a9e8639315530b683aca47

# network driver : Built-in / 3rd party extensions that giver virtual network features

# create a new container in my_app_network
vagrant@bionic64:~ % docker container run -d --name new_nginx --network my_app_network nginx
44f06d565e7576a48164f049bc58ed2babaa661e5c1e288eab6fc431c2cb9654

vagrant@bionic64:~ % docker network inspect my_app_network
[
    {
        "Name": "my_app_network",
        "Id": "9de8bdfbf0b5cafa7fc1096831ec721cdc7b254877a9e8639315530b683aca47",
         .................
        "Containers": {
            "44f06d565e7576a48164f049bc58ed2babaa661e5c1e288eab6fc431c2cb9654": {
                "Name": "new_nginx",
         ................. 
    }
]

# docker network connect : dynamically create an NIC container in an existing virtual network
vagrant@bionic64:~ % docker network connect 9de8bdfbf0b5cafa7fc1096831ec721 9931

vagrant@bionic64:~ % docker network inspect my_app_network
[
    {
        "Name": "my_app_network",
        "Id": "9de8bdfbf0b5cafa7fc1096831ec721cdc7b254877a9e8639315530b683aca47",
         .................
        "Containers": {
            "44f06d565e7576a48164f049bc58ed2babaa661e5c1e288eab6fc431c2cb9654": {
                "Name": "new_nginx",
         ................. 
            },
            "9931d78a6485c87d7c9f88ca307df3a968f228ed7f255643e0c36d7fe19e75f5": {
                "Name": "webhost",
         ................. 
    }
]
```

## Docker DNS
- Docker DNS

```bash:docker-dns
# docker dns : docker daemon has a built-in DNS server that containers use by default
# dns default names : docker defaults the hostname to the container's name, but it can be set alias
vagrant@bionic64:~ % docker container run -d --name my_nginx --network my_app_network nginx

# connect to my_nginx to install ping
vagrant@bionic64:~ % docker container exec -it my_nginx bash
root@d4abd4b561d6:/# apt-get update && apt-get install -y inetutils-ping

# try ping from my_nginx container to new_nginx container
vagrant@bionic64:~ % docker container exec -it my_nginx ping new_nginx
PING new_nginx (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: icmp_seq=0 ttl=64 time=0.110 ms
64 bytes from 172.20.0.2: icmp_seq=1 ttl=64 time=0.165 ms
64 bytes from 172.20.0.2: icmp_seq=2 ttl=64 time=0.084 ms
```

- Docker DNS Round Robin

```bash:docker-dns-round-robin
vagrant@bionic64:~ % docker network create dns-round-robin
c9208ef96323ea5c4ca2.........0efbd93c90617bff3f6e6ab4564123

# run es container in the background and connect it to dns-round-robin network (with alias)
vagrant@bionic64:~ % docker container run -d --network dns-round-robin --network-alias search elasticsearch:2
80a42ca1de69dd9bd2b4890917418b74b94a068084557a387eb35a4b579e4e0c
vagrant@bionic64:~ % docker container run -d --network dns-round-robin --network-alias search elasticsearch:2
4a6d2fb11f903b590ab22e407b110975fb1390077fd2a2eed239bad0e6a130ff

# test to make sure i can get to both of these with the same DNS names
vagrant@bionic64:~/Resources$ docker container run --rm --network dns-round-robin alpine:3.10 nslookup search
Name:      search
Address 1: 172.23.0.2 search.dns-round-robin
Address 2: 172.23.0.3 search.dns-round-robin


# curl to the es container to get both names
vagrant@bionic64:~ % docker container run --rm --net dns-round-robin centos curl -s search:9200
{
  "name" : "Raving Beauty",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "EoVuvBwlTgiDJBzbZzy0uQ",
  "version" : {
    "number" : "2.4.6",
    "build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
    "build_timestamp" : "2017-07-18T12:17:44Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.4"
  },
  "tagline" : "You Know, for Search"
}

vagrant@bionic64:~ % docker container run --rm --net dns-round-robin centos curl -s search:9200
{
  "name" : "Pietro Maximoff",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "uWarQcPnRhS51dC2A48inw",
  "version" : {
    "number" : "2.4.6",
    "build_hash" : "5376dca9f70f3abef96a77f4bb22720ace8240fd",
    "build_timestamp" : "2017-07-18T12:17:44Z",
    "build_snapshot" : false,
    "lucene_version" : "5.5.4"
  },
  "tagline" : "You Know, for Search"
}
```


## Troubleshooting
- no-space-left-on-device error
<br>参考記事：https://qiita.com/sakymark/items/df58ea2fd9179eddc566

```bash:no-space-left-on-device
vagrant@bionic64:~ % docker container run -it --name ubuntu ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
d51af753c3d3: Downloading [==================================================>]  28.56MB/28.56MB
fc878cd0a91c: Download complete
6154df8ff988: Download complete
fee5db0ff82f: Download complete
docker: write /var/lib/docker/tmp/GetImageBlob134356868: no space left on device.
See 'docker run --help'.

# Solution: delete unreferenced volume
vagrant@bionic64:~ % docker volume rm `docker volume ls -q -f dangling=true`

vagrant@bionic64:~ % docker container run -it --name ubuntu ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
d51af753c3d3: Pull complete
fc878cd0a91c: Pull complete
6154df8ff988: Pull complete
fee5db0ff82f: Pull complete
Digest: sha256:747d2dbbaaee995098c9792d99bd333c6783ce56150d1b11e333bbceed5c54d7
Status: Downloaded newer image for ubuntu:latest
root@d1dfcd290a4e:/#
```
- bash: vi: command not found
<br>参考記事：https://qiita.com/m-m00/items/a042bf9d5c7c85a64895

```bash:setting-proxy-in-ubuntu
apt-get update
apt-get install vim
```
- Single user persistent proxy settings

```bash:setting-proxy-in-ubuntu
sudo vi /etc/environment

http_proxy="AAA"
https_proxy="BBB"
no_proxy="localhost,127.0.0.1
```