CentOS8下的Docker使用初步探索 | 牧天的酒吧

CentOS8下的Docker使用初步探索

2021-09-09 18:17:16 于 技术

一、问题的起源

因为要部署项目管理软件禅道,了解了服务器搭建的环境,发现主机上已经搭建了Gitlab,配置的环境为Nginx+Postersql。同时又使用Docker搭建了新的Nginx服务和Mysql服务,用以运行另外一个项目。
在这样的情况下,如果要部署禅道,需要Nginx+PHP+MySQL,服务器的环境不太好进行配置,Gitlab的运行也就显得格格不入了。
基于上述情况,对服务器上的环境,使用Docker重新搭建,GitLab和禅道都考虑使用Docker来进行部署。同时,根据不同的来访域名,使主动自动分发相应域名到Docker实例中,方便后续的管理和使用。

二、什么是Docker

Docker是一个开源的应用容器引擎,基于Go语言,并遵从Apache2.0协议开源。
Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似iPhone的app),更重要的是容器性能开销极低。
Docker从17.03版本之后分为CE(Community Edition: 社区版)和EE(Enterprise Edition: 企业版)。

docker是一个用Go语言实现的开源项目,可以让我们方便的创建和使用容器,docker将程序以及程序所有的依赖都打包到docker container,这样你的程序可以在任何环境都会有一致的表现,这里程序运行的依赖也就是容器就好比集装箱,容器所处的操作系统环境就好比货船或港口,程序的表现只和集装箱有关系(容器),和集装箱放在哪个货船或者哪个港口(操作系统)没有关系。

因此我们可以看到docker可以屏蔽环境差异,也就是说,只要你的程序打包到了docker中,那么无论运行在什么环境下程序的行为都是一致的,程序员再也无法施展表演才华了,不会再有“在我的环境上可以运行”,真正实现“build once, run everywhere”。

此外docker的另一个好处就是快速部署,这是当前互联网公司最常见的一个应用场景,一个原因在于容器启动速度非常快,另一个原因在于只要确保一个容器中的程序正确运行,那么你就能确信无论在生产环境部署多少都能正确运行。

Docker的三个概念

镜像(Image):类似于虚拟机中的镜像,是一个包含有文件系统的面向Docker引擎的只读模板。任何应用程序运行都需要环境,而镜像就是用来提供这种运行环境的。例如一个Ubuntu镜像就是一个包含Ubuntu操作系统环境的模板,同理在该镜像上装上Apache软件,就可以称为Apache镜像。

容器(Container):类似于一个轻量级的沙盒,可以将其看作一个极简的Linux系统环境(包括root权限、进程空间、用户空间和网络空间等),以及运行在其中的应用程序。Docker引擎利用容器来运行、隔离各个应用。容器是镜像创建的应用实例,可以创建、启动、停止、删除容器,各个容器之间是是相互隔离的,互不影响。注意:镜像本身是只读的,容器从镜像启动时,Docker在镜像的上层创建一个可写层,镜像本身不变。

仓库(Repository):类似于代码仓库,这里是镜像仓库,是Docker用来集中存放镜像文件的地方。注意与注册服务器(Registry)的区别:注册服务器是存放仓库的地方,一般会有多个仓库;而仓库是存放镜像的地方,一般每个仓库存放一类镜像,每个镜像利用tag进行区分,比如Ubuntu仓库存放有多个版本(12.04、14.04等)的Ubuntu镜像。

三、Docker的底层实现

docker的底层实现docker基于Linux内核提供这样几项功能实现的:
NameSpace我们知道Linux中的PID、IPC、网络等资源是全局的,而NameSpace机制是一种资源隔离方案,在该机制下这些资源就不再是全局的了,而是属于某个特定的NameSpace,各个NameSpace下的资源互不干扰,这就使得每个NameSpace看上去就像一个独立的操作系统一样,但是只有NameSpace是不够。
Control groups虽然有了NameSpace技术可以实现资源隔离,但进程还是可以不受控的访问系统资源,比如CPU、内存、磁盘、网络等,为了控制容器中进程对资源的访问,Docker采用control groups技术(也就是cgroup),有了cgroup就可以控制容器中进程对系统资源的消耗了,比如你可以限制某个容器使用内存的上限、可以在哪些CPU上运行等等。

四、Docker是如何工作的

docker使用了常见的CS架构,也就是client-server模式,docker client负责处理用户输入的各种命令,比如docker build、docker run,真正工作的其实是server,也就是docker demon,值得注意的是,docker client和docker demon可以运行在同一台机器上。

1、docker build

当我们写完dockerfile交给docker“编译”时使用这个命令,那么client在接收到请求后转发给docker daemon,接着docker daemon根据dockerfile创建出“可执行程序”image。

2、docker run

有了“可执行程序”image后就可以运行程序了,接下来使用命令docker run,docker daemon接收到该命令后找到具体的image,然后加载到内存开始执行,image执行起来就是所谓的container。

3、docker pull

docker中image的概念就类似于“可执行程序”,我们可以从哪里下载到别人写好的应用程序呢?很简单,那就是APP Store,即应用商店。与之类似,既然image也是一种“可执行程序”,那么有没有"Docker Image Store"呢?答案是肯定的,这就是Docker Hub,docker官方的“应用商店”,你可以在这里下载到别人编写好的image,这样你就不用自己编写dockerfile了。docker registry 可以用来存放各种image,公共的可以供任何人下载image的仓库就是docker Hub。那么该怎么从Docker Hub中下载image呢,就是这里的docker pull命令了。因此,这个命令的实现也很简单,那就是用户通过docker client发送命令,docker daemon接收到命令后向docker registry发送image下载请求,下载后存放在本地,这样我们就可以使用image了。

五、CentOS8安装Docker服务

1、安装步骤

(1)下载docker-ce的repo

curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker-ce.repo

或者

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

(2)安装依赖

yum install https://download.docker.com/linux/fedora/30/x86_64/stable/Packages/containerd.io-1.2.6-3.3.fc30.x86_64.rpm

(3)安装docker-ce

dnf -y  install docker-ce  docker-ce-cli --nobest

(4)启动 docker

systemctl start docker

(5)查看 docker 版本信息

docker -v

(6)设置开机自动启动

systemctl enable --now docker

(8)卸载 docker

yum remove docker-ce
rm -rf /var/lib/docker

2、docker 命令

查看当前运行的所有容器

docker ps -a

停止所有容器(container),这样才能够删除其中的images:

docker stop $(docker ps -a -q)

查看镜像列表:

docker images

删除镜像(images),通过镜像(images)的id来指定删除谁

docker rmi <image id>

想要删除镜像(images)id为<None>的image的话可以用

docker rmi $(docker images | grep "^<none>" | awk "{print $3}")

要删除全部镜像(images)的话

docker rmi $(docker images -q)

从容器内拷贝文件到容器外,其中 mysqltest 是容器名称

 docker cp mysqltest:/etc/mysql/my.cnf /docker_volume/mysql/8.0/mysql_conf/

#4.其他命令请参考官网文档。

sudo systemctl start docker  //启动 Docker

六、使用Docker部署禅道

https://www.zentao.net/book/zentaopmshelp/405.html

1、拉取禅道最新版本镜像

sudo docker pull easysoft/zentao:latest

2、运行Docker容器实例

--name 容器名称
--p 端口映射,容器的80端口映射到主机8090端口,以访问web服务;容器的3306端口映射到主机的3307端口,以访问MySQL
-v 映射禅道的项目目录到主机的/junzhai/zentaopms/www,映射容器的mysql目录到主机的/junzhai/zentaopms/mysqldata。这样在删除容器实例时,可以保留项目相关源码和数据,以做备份。
-e 设置MySQL的登录密码
-d 运行的镜像名称
--restart=always 容器随系统自动启动
--network 指定所属的容器网络,用以和其他容器通讯
--network-alias 指定当前网络的名称,和其他容器以做区别,相当于IP地址的作用。

docker run --name zentao -p 8090:80 -p 3307:3306 -v /junzhai/zentaopms/www:/www/zentaopms -v /junzhai/zentaopms/mysqldata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d easysoft/zentao:latest --restart=always  --network junzhai --network-alias junzhai-zentao-server

3、进入容器配置项目

docker exec -it zentao /bin/bash
vi /etc/mysql/my.cnf

容器内apache配置文件目录:/etc/apache2/
容器内禅道目录:/www/zentaopms
容器内mysql配置文件目录: /etc/mysql/
容器内php配置文件目录:/etc/php/7.0/apache2

4、安装git和svn客户端

(如果不使用svn、git集成的话,不用安装)

apt-get install git -y
apt-get install subversion -y

5、配置Nginx

使用反向代理,通过域名的默认80端口访问对应8090端口。
反向代理的配置示例如下:

server {
    listen       80;
    server_name  localhost/zentaopms;
    
    # 日志
    access_log  /var/log/nginx/host.access.log  main;
 
    # 错误日志
    error_log /var/log/nginx/error.log error;
    
    # 二级目录代理禅道
    location /zentaopms {
        proxy_pass      http://182.120.0.3/zentaopms;
        proxy_redirect  off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
 
    # 首页
    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }
 
    # 50X错误页
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
 
}

针对本项目,Nginx的反向代理设置如下

http {
    upstream junzhai-chandao-server {
        server 39.105.87.98:8090;
    }

    server {
        listen       80;
        listen  [::]:80;

        server_name   填写需要访问的域名;

        location / {
            proxy_pass http://junzhai-chandao-server/;
            proxy_set_header Host $host;
        }
    }
}

七、迁移Gitlab服务至Docker中

1、备份主机中的Gitlab数据

https://www.cnblogs.com/zyrs/p/13653162.html

执行完成后,在/var/opt/gitlab/backups/目录下生成备份文件

gitlab-rake gitlab:backup:create

关闭主机中的Gitlab服务。Gitlab比较占内存,如果和Docker中的实例同时运行,得消耗服务器8-10个GB的内存。

2、在Docker中安装Gitlab

重要说明:要确保Docker和主机中的Gitlab版本一致
https://www.cnblogs.com/diaomina/p/12830449.html
https://mp.weixin.qq.com/s/6GyYlR9lpVcjgYmHMYLi0w
(1)拉取相应版本的Gitlab镜像

docker pull gitlab/gitlab-ce:13.7.0-ce.0

(2)运行Docker实例

docker run \
 -itd  \
 -p 9001:80 \
 -p 9002:22 \
 -p 9003:443 \
 -v /junzhai/gitlab/etc:/etc/gitlab  \
 -v /junzhai/gitlab/log:/var/log/gitlab \
 -v /junzhai/gitlab/opt:/var/opt/gitlab \
 --restart always \
 --privileged=true \
 --name gitlab \
  --network junzhai \
  --network-alias junzhai-gitlab-server \
 gitlab/gitlab-ce:13.7.0-ce.0

(3)将yum备份的压缩包拷贝到docker的backups目录下

docker cp /var/opt/gitlab/backups/1630921269_2021_09_06_13.7.0_gitlab_backup.tar gitlab:/var/opt/gitlab/backups

(4)在Docker中的Gitlab恢复备份

docker exec -it gitlab /bin/bash
chmod 777 -R /var/opt/gitlab/backups/
gitlab-rake gitlab:backup:restore BACKUP=1630921269_2021_09_06_13.7.0
gitlab-ctl restart

(5)检查是否成功

gitlab-rake gitlab:check SANITIZE=true

八、安装Docker的图形化管理工具Portainer

https://zhuanlan.zhihu.com/p/371592044

docker pull portainer/portainer
docker run -p 9000:9000 -p 8000:8000 --name portainer \
 --restart=always \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v /junzhai/portainer/data:/data \
 -d portainer/portainer

安装完成后,可以在主机的Nginx中设置反向代理,使用正常的域名访问Portainer。初次使用时,需要设置管理员账号。

■全文完

回主页