Não sei se entendi algo errado aqui, mas parece que só é possível definir mapeamentos de portas criando um novo contêiner a partir de uma imagem. Existe uma maneira de atribuir um mapeamento de porta a um contêiner Docker existente?
Não sei se entendi algo errado aqui, mas parece que só é possível definir mapeamentos de portas criando um novo contêiner a partir de uma imagem. Existe uma maneira de atribuir um mapeamento de porta a um contêiner Docker existente?
Respostas:
Você pode alterar o mapeamento de portas editando diretamente o hostconfig.json
arquivo em
/var/lib/docker/containers/[hash_of_the_container]/hostconfig.json
Você pode determinar o [hash_of_the_container] através do docker inspect <container_name>
comando e o valor do campo "Id" é o hash.
1) stop the container
2) stop docker service (per Tacsiazuma's comment)
3) change the file
4) restart your docker engine (to flush/clear config caches)
5) start the container
Portanto, você não precisa criar uma imagem com essa abordagem. Você também pode alterar o sinalizador de reinicialização aqui.
PS Você pode visitar https://docs.docker.com/engine/admin/ para saber como reiniciar corretamente o mecanismo do docker de acordo com a máquina host. Eu costumava sudo systemctl restart docker
reiniciar o mecanismo do docker que está sendo executado no Ubuntu 16.04
hostconfig.json
e config.v2.json
fazer isso funcionar. Use o link fornecido por @rohitmohta para ver os detalhes.
screen ~/Library/Containers/com.docker.docker/Data/com.docker.driver.amd64-linux/tty
Quando você obtiver o tty em execução, navegue para / var / lib / docker
Também estou interessado neste problema.
Como o @Thasmo mencionou, o encaminhamento de porta pode ser especificado SOMENTE com o comando docker run
(e docker create
).
Outros comandos, docker start
não possui -p
opção edocker port
exibe apenas os encaminhamentos atuais.
Para adicionar encaminhamentos de porta, eu sempre sigo estas etapas,
parar de executar o contêiner
docker stop test01
confirmar o contêiner
docker commit test01 test02
NOTA: A descrição acima test02
é uma nova imagem que estou construindo a partir do test01
contêiner.
re- correr a partir da imagem commited
docker run -p 8080:8080 -td test02
Onde o primeiro 8080 é a porta local e o segundo 8080 é a porta do contêiner.
docker start
?
Se por "existente" você quer dizer "em execução", não é possível (atualmente) adicionar um mapeamento de porta.
No entanto, você pode adicionar dinamicamente uma nova interface de rede com, por exemplo , Pipework , se precisar expor um serviço em um contêiner em execução sem parar / reiniciá-lo.
Não tenho certeza se você pode aplicar o mapeamento de portas a um contêiner em execução. Você pode aplicar o encaminhamento de porta enquanto executa um contêiner diferente de criar um novo contêiner.
$ docker run -p <public_port>:<private_port> -d <image>
começará a executar o contêiner. Este tutorial explica o redirecionamento de porta.
docker run
cria e inicia um novo contêiner. É equivalente a fazer docker create
seguido por docker start
.
A edição de hostconfig.json parece não estar funcionando agora. Ele termina apenas com essa porta sendo exposta, mas não publicada no host. Confirmar e recriar contêineres não é a melhor abordagem para mim. Ninguém mencionou docker network
?
A melhor solução seria usar proxy reverso na mesma rede
Crie uma nova rede se o contêiner anterior não estiver em nenhum nomeado.
docker network create my_network
Associe seu contêiner existente à rede criada
docker network connect my_network my_existing_container
Inicie um serviço de proxy reverso (por exemplo, nginx) publicando as portas necessárias, ingressando na mesma rede
docker run -d --name nginx --network my_network -p 9000:9000 nginx
Como opção, remova o default.conf no nginx
docker exec nginx rm /etc/nginx/conf.d/default.conf
Crie uma nova configuração nginx
server
{
listen 9000;
location / {
proxy_pass http://my_existing_container:9000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
Copie a configuração para o contêiner nginx.
docker cp ./my_conf.conf nginx:/etc/nginx/conf.d/my_conf.conf
Reinicie o nginx
docker restart nginx
Vantagens : Para publicar novas portas, você pode parar / atualizar / recriar com segurança o contêiner nginx como desejar, sem tocar no contêiner comercial. Se você precisar de um tempo de inatividade zero para o nginx, é possível adicionar mais serviços de proxy reverso ingressando na mesma rede. Além disso, um contêiner pode ingressar em mais de uma rede.
Editar:
Para inverter serviços proxy não-http, o arquivo de configuração é um pouco diferente. Aqui está um exemplo simples:
upstream my_service {
server my_existing_container:9000;
}
server {
listen 9000;
proxy_pass my_service;
}
No exemplo de Fujimoto, Youichi test01
é um contêiner, enquantotest02
é uma imagem.
Antes de fazer, docker run
você pode remover o contêiner original e atribuir ao contêiner o mesmo nome novamente:
$ docker stop container01
$ docker commit container01 image01
$ docker rm container01
$ docker run -d -P --name container01 image01
(Utilizando -P
para expor portas a portas aleatórias, em vez de atribuir manualmente).
Se você executar, docker run <NAME>
ela gerará uma nova imagem, o que provavelmente não é o que você deseja.
Se você deseja alterar uma imagem atual, faça o seguinte:
docker ps -a
Pegue o ID do seu container de destino e vá para:
cd /var/lib/docker/containers/<conainerID><and then some:)>
Pare o recipiente:
docker stop <NAME>
Mude os arquivos
vi config.v2.json
"Config": {
....
"ExposedPorts": {
"80/tcp": {},
"8888/tcp": {}
},
....
},
"NetworkSettings": {
....
"Ports": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "80"
}
],
E mudar arquivo
vi hostconfig.json
"PortBindings": {
"80/tcp": [
{
"HostIp": "",
"HostPort": "80"
}
],
"8888/tcp": [
{
"HostIp": "",
"HostPort": "8888"
}
]
}
Reinicie sua janela de encaixe e ela deve funcionar.
O contrário, se você não se sentir confortável com as tabelas de IP da configuração de profundidade do Docker, seria seu amigo.
iptables -t nat -A DOCKER -p tcp --dport ${YOURPORT} -j DNAT --to-destination ${CONTAINERIP}:${YOURPORT}
iptables -t nat -A POSTROUTING -j MASQUERADE -p tcp --source ${CONTAINERIP} --destination ${CONTAINERIP} --dport ${YOURPORT}
iptables -A DOCKER -j ACCEPT -p tcp --destination ${CONTAINERIP} --dport ${YOURPORT}
Este é apenas um truque, não uma maneira recomendada de como isso funciona com o meu cenário, porque eu não conseguia parar o contêiner, espero que também o ajude.
DOCKER_PORT
para MACHINE_PORT
que as peças devem ser alteradas?
usamos ferramentas úteis como ssh para fazer isso facilmente.
Eu estava usando o host do ubuntu e a imagem do docker baseada no ubuntu.
quando uma nova porta é necessária para ser mapeada,
dentro da janela de encaixe, execute o seguinte comando
ssh -R8888:localhost:8888 <username>@172.17.0.1
172.17.0.1 era o ip da interface do docker (você pode obtê-lo executando
ifconfig docker0 | grep "inet addr" | cut -f2 -d":" | cut -f1 -d" "
no host).
aqui eu tinha a porta 8888 local mapeada de volta para os hosts 8888. você pode alterar a porta conforme necessário.
se você precisar de mais uma porta, poderá matar o ssh e adicionar mais uma linha de -R a essa nova porta.
Eu testei isso com o netcat.
Para usuários de Windows e Mac, existe outra maneira bastante fácil e amigável de alterar a porta de mapeamento:
baixar kitematic
vá para a página de configurações do contêiner, na guia portas, você pode modificar diretamente a porta publicada lá.
inicie o contêiner novamente
Resposta curta: Você não pode atribuir um mapeamento de porta a um contêiner Docker existente
Você precisa de um novo contêiner ... lide com isso.
Se você simplesmente deseja alterar a porta do contêiner em execução, faça:
sudo docker stop NAME
sudo docker run -d -p 81:80 NAME
enquanto que:
"-d" para segundo plano / instalar a janela de encaixe
"-p" ativa o mapeamento de portas
Porta externa (exposta) "81" usada para acessar com o navegador
Porta de escuta do contêiner de docker interno "80"
docker run
comando, NAME
é o nome da imagem a ser executado a partir de um recipiente, enquanto que na docker stop
o NAME
se refere ao nome do recipiente para paragem.