gitlab docker容器 配置git hooks

一、官方文档

通常,Git钩子被放置在存储库或项目的hooks目录中。GitLab从每个项目的hooks目录创建一个符号链接到gitlab-shell hooks目录,以便于在gitlab-shell升级之间进行维护。因此,定制钩子的实现方式略有不同。一旦创建了钩子,行为就完全一样了。

按照以下步骤设置自定义挂钩:

  1. 选择一个需要定制Git钩子的项目。
  2. 在GitLab服务器上,进入到项目的存储库目录。对于从源安装,路径通常是/home/git/repositories/<group>/<project>.git。对于Omnibus安装路径通常/var/opt/gitlab/git-data/repositories/<group>/<project>.git
  3. 在此位置创建一个新的目录custom_hooks
  4. 在新custom_hooks目录中创建一个名称匹配钩子类型的文件。例如push后出发的post-receive 没有扩展名。
  5. 使钩子文件可执行,并确保它由git拥有。
  6. 编写代码,使Git hook功能按预期方式运行。钩子可以是任何语言。确保顶部的“shebang”正确反映了语言类型。例如,如果脚本在Ruby中,shebang可能会是 #!/usr/bin/env ruby

二 、开始配置

进入gitlab容器内创建钩子文件(mall-组名 new_mall-项目名)

[root@VM_204_108_centos /]# docker exec -it gitlab /bin/bash

root@git:/# cd /var/opt/gitlab/git-data/repositories/mall/new_mall.git/

root@git:/var/opt/gitlab/git-data/repositories/mall/new_mall.git# mkdir custom_hooks/

root@git:/var/opt/gitlab/git-data/repositories/mall/new_mall.git# cd custom_hooks/

root@git:/var/opt/gitlab/git-data/repositories/mall/new_mall.git/custom_hooks# vim post-receive



#!/bin/bash

# 172.19.0.1 这个为宿主的虚拟IP

#我在宿主上边/shell-script/new_mall/git-pull.sh 里边写了同步代码的逻辑

#此处需要生成git用户的id_rsa.pub并导入到宿主的root用户认证中去 这是里就不说了。百度很多 linux公私钥认证

ssh root@172.19.0.1 "sh /shell-script/new_mall/git-pull.sh"

docker 官方的镜像大多基于debian,但是官方源更新失败,如何更换成中国源

#更新apt-get源 使用163的源
RUN mv /etc/apt/sources.list /etc/apt/sources.list.bak && \
    echo "deb http://mirrors.163.com/debian/ jessie main non-free contrib" >/etc/apt/sources.list && \
    echo "deb http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list && \
    echo "deb-src http://mirrors.163.com/debian/ jessie main non-free contrib" >>/etc/apt/sources.list && \
    echo "deb-src http://mirrors.163.com/debian/ jessie-proposed-updates main non-free contrib" >>/etc/apt/sources.list

使用Docker Compose部署基于Sentinel的高可用Redis集群

大家一定非常熟悉如何利用Docker启动单个Redis容器用于开发环境,本文将介绍如何利用Docker Compose模板在本机和云端部署基于Sentinel的高可用Redis 3集群。

大家一定非常熟悉如何利用Docker启动单个Redis容器用于开发环境,本文将介绍如何利用Docker Compose模板在本机和云端部署基于Sentinel的高可用Redis 3集群。

Redis集群可以在一组redis节点之间实现高可用性和sharding。今天我们重点围绕master-slave的高可用模式来进行讨论,在集群中会有1个master和多个slave节点。当master节点失效时,应选举出一个slave节点作为新的master。然而Redis本身(包括它的很多客户端)没有实现自动故障发现并进行主备切换的能力,需要外部的监控方案来实现自动故障恢复。

Redis Sentinel是官方推荐的高可用性解决方案。它是Redis集群的监控管理工具,可以提供节点监控、通知、自动故障恢复和客户端配置发现服务。

今天我们的部署模型是 Redis Sentinel 介绍的实例二,也是实战中比较常见的一种部署模式:

本文所有示例代码都可以从 https://github.com/AliyunContainerService/redis-cluster 获得

本文采用的Redis镜像全部基于Docker提供的Redis官方镜像3.2.1

单机部署Redis集群

下面的测试需要本地环境已经安装Docker Engine和Docker Compose,推荐使用Docker for Mac/Windows。想在云端部署的同学可以直接跳到下一节

下载代码

git clone https://github.com/AliyunContainerService/redis-cluster
cd redis-cluster

目录下面的docker-compose.yml模板定义Redis集群的服务组成

master:
  image: redis:3
slave:
  image: redis:3
  command: redis-server --slaveof redis-master 6379
  links:
    - master:redis-master
sentinel:
  build: sentinel
  environment:
    - SENTINEL_DOWN_AFTER=5000
    - SENTINEL_FAILOVER=5000    
  links:
    - master:redis-master
    - slave

在模板中定义了下面一系列服务

  • master: Redis master
  • slave: Redis slave
  • sentinel: Redis Sentinel

其中sentinel服务的Docker镜像是由 “./sentinel” 目录中的Dockerfile构建完成,只是在官方Redis镜像上添加了sentinel.conf配置文件,并以sentinel模式启动容器。其配置文件如下,其中包含了sentinel对名为”mymaster”的集群的监控配置:

sentinel monitor mymaster redis-master 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 5000

细节请参见sentinel.conf配置自身。

注意:

  • slave和sentinel容器初始化配置的Redis master节点主机名为”redis-master”,这里我们利用了Docker容器连接的别名机制来连接master和sentinel/slave容器实例
  • 由于我们会部署3个Sentinel,我们把sentinel的”quorum”设置为2,只有两个sentinel同意故障切换,才会真正切换相应的redis master节点。

下面我们先构建 sentinel 服务所需 Docker image

docker-compose build

一键部署并启动Redis集群

docker-compose up -d

这时我们可以检查集群状态,应该是包含3个容器,1个master, 1个slave,和1个sentinel

docker-compose ps

显示结果如下

         Name                        Command               State          Ports        
--------------------------------------------------------------------------------------
rediscluster_master_1     docker-entrypoint.sh redis ...   Up      6379/tcp            
rediscluster_sentinel_1   docker-entrypoint.sh redis ...   Up      26379/tcp, 6379/tcp 
rediscluster_slave_1      docker-entrypoint.sh redis ...   Up      6379/tcp     

我们可以伸缩sentinel的实例数量到3个

docker-compose scale sentinel=3

伸缩slave的实例数量到2个,这样我们就有3个redis实例了(包含一个master)

docker-compose scale slave=2

检查集群状态,结果如下

docker-compose ps

         Name                        Command               State          Ports        
--------------------------------------------------------------------------------------
rediscluster_master_1     docker-entrypoint.sh redis ...   Up      6379/tcp            
rediscluster_sentinel_1   docker-entrypoint.sh redis ...   Up      26379/tcp, 6379/tcp 
rediscluster_sentinel_2   docker-entrypoint.sh redis ...   Up      26379/tcp, 6379/tcp 
rediscluster_sentinel_3   docker-entrypoint.sh redis ...   Up      26379/tcp, 6379/tcp 
rediscluster_slave_1      docker-entrypoint.sh redis ...   Up      6379/tcp            
rediscluster_slave_2      docker-entrypoint.sh redis ...   Up      6379/tcp            

我们可以利用下面的测试脚本来模拟master节点失效,并验证Redis集群的自动主从切换。

./test.sh

这个测试脚本实际上利用 docker pause 命令将 Redis master容器暂停,sentinel会发现这个故障并将master切换到其他一个备用的slave上面。

执行结果如下

Redis master: 172.17.0.2
Redis Slave: 172.17.0.3
------------------------------------------------
Initial status of sentinel
------------------------------------------------
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.2:6379,slaves=2,sentinels=3
Current master is
172.17.0.2
6379
------------------------------------------------
Stop redis master
rediscluster_master_1
Wait for 10 seconds
Current infomation of sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.3:6379,slaves=2,sentinels=3
Current master is
172.17.0.3
6379
------------------------------------------------
Restart Redis master
rediscluster_master_1
Current infomation of sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.3:6379,slaves=2,sentinels=3
Current master is
172.17.0.3
6379

我们可以利用Docker Compose方便地在本地验证Redis集群的部署和故障恢复

 

转载自:https://yq.aliyun.com/articles/57953

docker-compose 使用

在此页面上,您将构建一个在Docker Compose上运行的简单的Python Web应用程序。该应用程序使用Flask框架,并在Redis中维护一个命中计数器。虽然示例使用Python,但这里展示的概念应该是可以理解的,即使您不熟悉它。

步骤1:设置

  1. 为项目创建一个目录:
    $ mkdir composetest
    $ cd composetest
    
  2. app.py在您的项目目录中创建一个名为“
    from flask import Flask
    from redis import Redis
    
    app = Flask(__name__)
    redis = Redis(host='redis', port=6379)
    
    @app.route('/')
    def hello():
        count = redis.incr('hits')
        return 'Hello World! I have been seen {} times.\n'.format(count)
    
    if __name__ == "__main__":
        app.run(host="0.0.0.0", debug=True)
    

    在此示例中,redis是应用程序网络上的redis容器的主机名。我们使用Redis的默认端口6379

  3. requirements.txt在您的项目目录中创建另一个文件,并将其粘贴到:
    flask
    redis
    

这些定义了应用程序的依赖关系。

步骤2:创建一个Docker文件

在此步骤中,您将编写一个构建Docker映像的Docker文件。该图像包含Python应用程序所需的所有依赖项,包括Python本身。

在您的项目目录中,创建一个名为Dockerfile并粘贴以下内容的文件:

FROM python:3.4-alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

这告诉Docker:

  • 从Python 3.4映像开始构建一个图像。
  • 将当前目录添加./code图像中的路径中。
  • 将工作目录设置为/code
  • 安装Python依赖关系。
  • 将容器的默认命令设置为python app.py

有关如何编写Dockerfiles的更多信息,请参阅Docker用户指南 和Dockerfile引用

步骤3:在Compose文件中定义服务

创建一个docker-compose.yml在你的项目目录中调用的文件并粘贴以下内容:

version: '2'
services:
  web:
    build: .
    ports:
     - "5000:5000"
    volumes:
     - .:/code
  redis:
    image: "redis:alpine"

此撰写文件定义了两个服务,webredis。网络服务:

  • 使用从Dockerfile当前目录中构建的映像。
  • 将容器上暴露的端口5000转发到主机上的端口5000。我们使用Flask Web服务器的默认端口5000
  • 将主机上的项目目录安装在/code容器内,允许您修改代码,而无需重新构建映像。

redis服务使用从Docker Hub注册表提取的公共 Redis映像。

提示:如果您的项目在Users目录(cd ~)之外,则需要共享您正在使用的Dockerfile和卷的驱动器或位置。如果出现指示未找到应用程序文件的运行时错误,则会拒绝卷挂载,否则服务无法启动,请尝试启用文件或驱动器共享。卷安装需要在C:\Users(Windows)或/Users(Mac)以外的项目使用共享驱动器 ,并且对于使用Linux容器的 Docker for Windows的任何项目都是必需的。有关详细信息,请参阅Docker for Windows上的共享驱动器, Docker for Mac上的文件共享以及如何在容器中管理数据的常规示例。

步骤4:使用Compose构建和运行您的应用程序

  1. 从您的项目目录,启动您的应用程序。
     $ docker-compose up
     Pulling image redis...
     Building web...
     Starting composetest_redis_1...
     Starting composetest_web_1...
     redis_1 | [8] 02 Jan 18:43:35.576 # Server started, Redis version 2.8.3
     web_1   |  * Running on http://0.0.0.0:5000/
     web_1   |  * Restarting with stat
    

    Compose提取Redis映像,为代码构建映像,并启动您定义的服务。

  2. http://0.0.0.0:5000/在浏览器中输入以查看运行的应用程序。

    如果您在Linux上使用Docker,那么Web应用程序现在应该在Docker守护程序主机上监听5000端口。如果http://0.0.0.0:5000 不解决,你也可以尝试http://localhost:5000

    如果您在Mac上使用Docker Machine,请使用docker-machine ip MACHINE_VM以获取Docker主机的IP地址。然后,http://MACHINE_VM_IP:5000在浏览器中打开。

    您应该在浏览器中看到一条消息:

    Hello World! I have been seen 1 times.

  3. 刷新页面。

    数字应该增加。

提示:您可以列出本地图像docker image ls并使用它们进行检查docker inspect <tag or id>。在这一点上清单图片应返回redisweb

步骤5:更新应用程序

因为使用卷将应用程序代码安装到容器中,您可以更改其代码并立即查看更改,而无需重新构建映像。

  1. 改变问候语app.py并保存。例如:
    return 'Hello from Docker! I have been seen {} times.\n'.format(count)
    
  2. 在浏览器中刷新应用程序。应该更新问候语,计数器应该继续递增。

注意:如果您在较旧的Windows操作系统上使用Oracle VirtualBox,则可能会遇到此VB故障单中所述的共享文件夹问题。较新的Windows系统满足Docker for Windows的要求,不需要VirtualBox。

步骤6:尝试一些其他命令

如果您想在后台运行您的服务,您可以将-d标志(“分离”模式)传递给docker-compose up并用于docker-compose ps查看当前运行的内容:

$ docker-compose up -d
Starting composetest_redis_1...
Starting composetest_web_1...

$ docker-compose ps
Name                 Command            State       Ports
-------------------------------------------------------------------
composetest_redis_1   /usr/local/bin/run         Up
composetest_web_1     /bin/sh -c python app.py   Up      5000->5000/tcp

docker-compose run命令允许您为您的服务运行一次性命令。例如,要查看web服务可用的环境变量 :

$ docker-compose run web env

docker-compose --help参阅其他可用的命令。您还可以为bash和zsh shell 安装命令完成,这也将显示可用的命令。

如果您开始撰写docker-compose up -d,您可能希望在完成后停止您的服务:

$ docker-compose stop

您可以把所有的东西都放下,用down 指令完全取出容器。传递--volumes也删除Redis容器使用的数据量:

$ docker-compose down --volumes

在这一点上,您已经看到了Compose的工作原理。

Agular4 路由

Angular Route 导航

  1. Routes:路由配置,保存着哪个Url对应展示哪个组件,以及在哪个TouterOutlet中展示组件。
  2. RouteOutlet: 在Html中标记路由内容呈现位置的占位符指令。
  3. Router:负责在运行时执行路由的对象,可以通过调用器navigate()和navigateByUrl()方法来导航到一个指定的路由。
  4. RouterLink 在Html中声明路由导航用的指令。
  5. ActivatedRoute当前激活的路由对象,保存着当前路由的信息,如路由地址、路由参数等。

路由配置

src\app\app-routing.module.ts

const routes: Routes = [
  //路由为空时的指向
  {path: '', componet: HomeComponet}
  //将localhost:4200/home 路由指向HomeConpnent组件
  {path: 'home', component: HomeComponent},
  //将未匹配到的路由指向Code404Componet组件
  {path: '**', component: Code404Component},
];

插座

src\app\app.component.html

<router-outlet></router-outlet>

用来指示组件显示的位置

routerLink

<a [routerLink]="['/']">主页</a>
<a [routerLink]="['/product']">商品详情</a>

路由跳转

src\app\app-routing.module.ts

<input type="button" value="商品详情" (click)="toProductDetails()">

src\app\app.component.ts

//拿Router对象
constructor(private router: Router) {

}
//导航到目录路由
toProductDetails() {
  this.router.navigate(['/product']);
}

在路由时传递数据

在查询参数中传递数据

src\app\app.component.html

<a [routerLink]="['/product']" [queryParams]="{id: 1}">商品详情</a>

src\app\product\product.component.ts

//存储传递过来的ID
private productId: number;

//获得参数信息
constructor(private routeInfo: ActivatedRoute) { }

ngOnInit() {
  this.productId = this.routeInfo.snapshot.params['id'];
}

在路由路径中传递数据

src\app\app-routing.module.ts

const routes: Routes = [
  {path: 'product/:id', component: ProductComponent},
];

src\app\app.component.html

<a [routerLink]="['/product', 2]">商品详情</a>

src\app\product\product.component.ts

参数快照方式获取:(不从新调用ngOnInit方法)

this.productId = this.routeInfo.snapshot.params['id'];

参数订阅方式获取

this.routeInfo.params.subscribe((params: Params) => this.productId = params['id']);

在路由配置中传递数据

重定向路由

src\app\app-routing.module.ts

const routes: Routes = [
  {path: '', redirectTo: '/home', pathMatch: 'full'},
];

子路由

src\app\app-routing.module.ts

const routes: Routes = [
  {path: 'product/:id', component: ProductComponent, children: [
    {path: '', component: ProductDescComponent},
    {path: 'seller/:id', component: SellerInfoComponent},
  ]},
];

src\app\product\product.component.html

注意前边的”.”

<a [routerLink]="['./']">商品描述</a>
<a [routerLink]="['./seller', 99]">卖家信息</a>
<router-outlet></router-outlet>

辅助路由

声明一个带有name属性的插座

src\app\app.component.html

<router-outlet name="aux"></router-outlet>

在路由配置里边配置aux这个插座上可以显示哪些组件

src\app\app-routing.module.ts

{path: 'chat', component: ChatComponent, outlet: 'aux'},

指定路由跳转时主插座显示哪个组件,辅助插座上显示哪个组件

跳转到指定组件显示辅助路由中的组件

<a [routerLink]="[{outlets: {primary: 'aux', aux: 'chat'}}]">开始聊天</a>

不跳转主路由

<a [routerLink]="[{outlets: {aux: 'chat'}}]">开始聊天</a>

路由守卫(钩子)

  1. CanActivate:处理导航到某个路由的情况
  2. CanDeactivate:处理从当前路由离开的情况
  3. resolve:在路由激活之前获得路由所需数据

CanActivate 

新建文件和文件夹

  • src\app\guard
  • src\app\guard\login.guard.ts
import {CanActivate} from '@angular/router';

export class LoginGuard implements CanActivate {

  canActivate() {

    let loggedIn: boolean = Math.random() < 0.5;

    if (!loggedIn) {
      console.log('用户未登录');
    }

    return loggedIn;
  }

}

src\app\app-routing.module.ts

const routes: Routes = [
  {path: '', redirectTo: '/home', pathMatch: 'full'},
  {path: 'home', component: HomeComponent},
  {path: 'chat', component: ChatComponent, outlet: 'aux'},
  {path: 'product/:id', component: ProductComponent, children: [
    {path: '', component: ProductDescComponent},
    {path: 'seller/:id', component: SellerInfoComponent},
  ], canActivate: [LoginGuard]},
  {path: '**', component: Code404Component},
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [LoginGuard]
})

CanDeactivate

src\app\guard\unsaved.guard.ts

import {CanDeactivate} from '@angular/router';
import {ProductComponent} from '../product/product.component';

export class UnsavedGuard implements CanDeactivate<ProductComponent> {
  canDeactivate(component: ProductComponent) {
    return window.confirm('您好未保存,确定要离开么?');
  }
}

src\app\app-routing.module.ts

const routes: Routes = [
  {path: '', redirectTo: '/home', pathMatch: 'full'},
  {path: 'home', component: HomeComponent},
  {path: 'chat', component: ChatComponent, outlet: 'aux'},
  {path: 'product/:id', component: ProductComponent, children: [
    {path: '', component: ProductDescComponent},
    {path: 'seller/:id', component: SellerInfoComponent},
  ], canActivate: [LoginGuard], canDeactivate: [UnsavedGuard]},
  {path: '**', component: Code404Component},
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
  providers: [LoginGuard, UnsavedGuard]
})

 

docker stacks 堆栈

介绍

docker 集群中,学习了如何设置docker集群,这是一组运行docker的机器,并将运用程序部署到其上,容器在多台机器上协同运行。

在本篇文档中,将学习分布式应用程序堆栈。堆栈是一组相互关联的服务,它们共享依赖关系,并且可以一起编排和缩放。单个堆栈能够定义和协调整个应用程序的功能(非常复杂的应用程序可能希望使用多个堆栈)。当您创建一个Compose文件并使用时,您在技术上一直在使用堆栈docker stack deploy。但是,这是单个主机上运行的单一服务堆栈,这通常不会在生产中发生。在这里,您将获取所学知识,使多个服务相互关联,并在多台计算机上运行。

添加新服务并重新部署

很容易为我们的docker-compose.yml文件添加服务。首先,我们添加一个免费的可视化服务,让我们看看我们的群集如何调度容器。

  1. docker-compose.yml在编辑器中打开并用以下内容替换其内容。一定要更换username/repo:tag你的镜像。
    version: "3"
    services:
      web:
        # replace username/repo:tag with your name and image details
        image: username/repo:tag
        deploy:
          replicas: 5
          restart_policy:
            condition: on-failure
          resources:
            limits:
              cpus: "0.1"
              memory: 50M
        ports:
          - "80:80"
        networks:
          - webnet
      visualizer:
        image: dockersamples/visualizer:stable
        ports:
          - "8080:8080"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock"
        deploy:
          placement:
            constraints: [node.role == manager]
        networks:
          - webnet
    networks:
      webnet:
    

    这里唯一新来的是对等服务web,命名visualizer。您将在这里看到两个新的东西:一个volumes关键字,让可视化程序访问Docker的主机套接字文件以及一个placement关键字,确保这个服务只能在群集管理器上运行,而不是工作人员。这是因为由Docker创建的开源项目构建的这个容器显示了在图中以群集运行的Docker服务。

    稍后我们会详细讨论放置约束和卷。

  2. 将此新docker-compose.yml文件复制到群组管理器myvm1
    docker-machine scp docker-compose.yml myvm1:~
    
  3. docker stack deploy在管理员上重新运行命令,任何需要更新的服务将被更新:
    $ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
    Updating service getstartedlab_web (id: angi1bf5e4to03qu9f93trnxm)
    Updating service getstartedlab_visualizer (id: l9mnwkeq2jiononb5ihz9u7a4)
    
  4. 看看可视化器。您在Compose文件中看到在visualizer8080端口上运行docker-machine ls。通过运行获取您的一个节点的IP地址。转到8080端口的IP地址,您将看到可视化运行:

单个副本visualizer正如您所期望的那样在主服务器上运行,并且五个实例web分布在群集中。您可以通过运行docker stack ps <stack>以下方式来证实这种可视化:

docker-machine ssh myvm1 "docker stack ps getstartedlab"

可视化器是一种独立的服务,可以在任何包含在堆栈中的应用程序中运行。它不依赖于其他任何东西。现在让我们创建一个确实具有依赖性的服务:Redis服务将提供一个访客计数器。

通过8080无法访问请进入虚拟机查看netstat -anp | grep 8080 如果没有

执行docker images 查看是否有dockersamples/visualizer:stable 镜像

如果没有可能是网络下载过慢造成的,建议更换docker源为国内的,更换方法前边以有介绍

保存数据

让我们再次浏览相同的工作流程,以添加用于存储应用数据的Redis数据库。

  1. 保存这个新docker-compose.yml文件,最后添加一个Redis服务。一定要更换username/repo:tag你的镜像。
    version: "3"
    services:
      web:
        # replace username/repo:tag with your name and image details
        image: username/repo:tag
        deploy:
          replicas: 5
          restart_policy:
            condition: on-failure
          resources:
            limits:
              cpus: "0.1"
              memory: 50M
        ports:
          - "80:80"
        networks:
          - webnet
      visualizer:
        image: dockersamples/visualizer:stable
        ports:
          - "8080:8080"
        volumes:
          - "/var/run/docker.sock:/var/run/docker.sock"
        deploy:
          placement:
            constraints: [node.role == manager]
        networks:
          - webnet
      redis:
        image: redis
        ports:
          - "6379:6379"
        volumes:
          - ./data:/data
        deploy:
          placement:
            constraints: [node.role == manager]
        networks:
          - webnet
    networks:
      webnet:
    

    Redis在Docker hub 有一个官方镜像,并被授予了简短的image名字redis,所以username/repo在这里没有符号。Redis端口6379已由Redis预配置为从容器暴露给主机,在我们的Compose文件中,我们将其从主机公开,因此您可以真正输入您的任何IP节点进入Redis Desktop Manager并管理此Redis实例,如果您这样选择。

    最重要的是,redis规范中有几件事情使数据在该堆栈的部署之间保持不变:

    • redis 总是在管理器上运行,所以它总是使用相同的文件系统。
    • redis访问主机文件系统中的任意目录在/data容器内,Redis存储数据。

    在一起,这是在您的主机的物理文件系统中为Redis数据创建“真实目录”。没有这个,Redis会将其数据存储 /data在容器的文件系统内,如果该容器被重新部署,它将被清除。

    来源有两个部分:

    • 您放置在Redis服务上的放置约束,确保它始终使用相同的主机。
    • 您创建的卷允许容器访问./data(在主机上)为/data(在Redis容器内)。当容器来回走动时,存储在./data指定主机上的文件将持续存在,从而实现连续性。

    您已准备好部署新的Redis使用堆栈。

  2. ./data在管理器上创建一个目录:
    $ docker-machine ssh myvm1 "mkdir ./data"
    
  3. 通过以下方式复制新docker-compose.yml文件docker-machine scp
    $ docker-machine scp docker-compose.yml myvm1:~
    
  4. 再运行docker stack deploy一次
    $ docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"
    
  5. 检查您的一个节点(例如http://192.168.99.101)的网页,您将看到访客计数器的结果,该计数器现在已存在,并存储有关Redis的信息。

    另外,检查可视化在上的任一节点的IP地址端口8080,你会看到redis与一起运行服务webvisualizer服务。

docker Swarms 集群

安装 Docker Machine

下载地址:https://docs.docker.com/machine/install-machine/#installing-machine-directly

如果不能下载,直接进入github下载二进制包来放在/usr/local/bin目录中即可

了解集群

集群是运行Docker并加入集群的一组机器。之后,您继续运行您以前使用的Docker命令,但现在它们是由群组管理器在集群上执行的。集群中的机器可以是物理的或虚拟的。加入群组后,它们被称为节点

Swarm管理员可以使用几种策略来运行容器,例如“最简单的节点” – 这些容器填充了最少使用的机器。或“全局”,它确保每个机器只能获得指定容器的一个实例。您可以指示群组经理在撰写文件中使用这些策略,就像您已经使用的策略一样。

群体管理器是集群中唯一可以执行命令的机器,或授权其他机器作为工作人员加入集群。工作人员只是提供能力,没有权力告诉任何其他机器它可以做什么和不能做什么。

到目前为止,您已经在本地计算机上以单主机模式使用Docker。但是Docker也可以切换到集群,这就是使用集群。立即启用集群模式使当前的机器成为集群管理器。从那时起,Docker将运行您正在管理的集群上执行的命令,而不仅仅是在当前的机器上运行。

设置你的群

一个集群由多个节点组成,可以是物理机或虚拟机。基本概念很简单:运行docker swarm init以启用集群式,使您当前的机器成为集群管理器,然后docker swarm join在其他机器上运行 ,让他们以工作人员身份加入集群。选择下面的标签,看看它是如何在各种上下文中播放的。我们将使用虚拟机快速创建双机集群并将其转换成集群。

创建一个集群

首先,您需要一个可以创建虚拟机的管理程序,因此可以为您的机器的操作系统安装VirtualBox

注意:如果您安装的是具有Hyper-V的Windows系统,例如Windows 10,则不需要安装VirtualBox,您应该使用Hyper-V。通过单击上面的Hyper-V选项来查看Hyper-V系统的说明。

现在,docker-machine使用VirtualBox驱动程序创建几个虚拟机:

$ docker-machine create --driver virtualbox myvm1
$ docker-machine create --driver virtualbox myvm2

命令会自动下载boot2docker.iso镜像,如果被墙命令执行失败,则复制命令日志中的url自行去下载,我就是自行下载的。下载后放到任意目录,这里我放在了/data/boot2docker.iso这里。执行下边的命令创建虚拟机

docker-machine create --virtualbox-boot2docker-url file:///data/boot2docker.iso --driver virtualbox myvm1
docker-machine create --virtualbox-boot2docker-url file:///data/boot2docker.iso --driver virtualbox myvm2

您现在有两个虚拟机创建,命名myvm1myvm2(如docker-machine ls 显示)。第一个将作为经理,执行docker命令并认证工人加入群众,第二个将是一个工人。

您可以使用命令发送到您的虚拟机docker-machine ssh。指示myvm1 成为一个群组经理,docker swarm init你会看到这样的输出:

$ docker-machine ssh myvm1 "docker swarm init"
Swarm initialized: current node <node ID> is now a manager.

To add a worker to this swarm, run the following command:

  docker swarm join \
  --token <token> \
  <ip>:<port>

显示错误–advertise-addr?

复制myvm1运行的IP地址docker-machine ls,然后docker swarm init再次运行该 命令,使用该IP并指定端口2377 (与端口连接)–advertise-addr。例如:

docker-machine ssh myvm1 “docker swarm init –advertise-addr 192.168.99.100:2377”

无法连通创建的主机,可以执行下边的命令

sudo ifconfig vboxnet0 down && sudo ifconfig vboxnet0 up

删除vitualbox中的网络

您可以看到,响应docker swarm init包含一个预先配置的 docker swarm join命令,您可以在要添加的任何节点上运行。复制此命令,并将其发送到myvm2via docker-machine sshmyvm2 加入您的新群组作为工作人员:

$ docker-machine ssh myvm2 "docker swarm join \
--token <token> \
<ip>:<port>"

This node joined a swarm as a worker.

恭喜,你已经创建了你的第一个群。

注意:注意端口是2377!!!您也可以运行docker-machine ssh myvm2,不附加命令来打开该VM上的终端会话。键入exit当你准备返回到主shell提示符。以这种方式粘贴join命令可能会更容易。

使用ssh连接到(docker-machine ssh myvm1),并运行docker node ls在该群查看节点:

docker@myvm1:~$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
brtu9urxwfd5j0zrmkubhpkbd     myvm2               Ready               Active              
rihwohkh3ph38fhillhhb84sk *   myvm1               Ready               Active              Leader

键入exit以退出该机器。

或者,包装命令docker-machine ssh不要直接登录和退出。例如:

docker-machine ssh myvm1 "docker node ls"

在集群上部署应用程序

困难的部分已经结束了。现在您只需重复上一篇文档中创建的docker-compose.yml进程,即可部署在新的集群中。只要记住,只有群管理者myvm1可以发送执行Docker命令; 工人只是为了执行。

使用以下命令将docker-compose.yml复制到集群管理器myvm1的主目录(别名:):~docker-machine scp

docker-machine scp docker-compose.yml myvm1:~

现在myvm1通过发送与docker stack deploy上篇文档中myvm1使用 的相同的命令来使用其作为群组管理器的权力来部署您的应用程序docker-machine ssh

docker-machine ssh myvm1 "docker stack deploy -c docker-compose.yml getstartedlab"

这就是应用程序部署在集群上。

将您在上一篇文档中使用的所有命令包含在调用中docker-machine ssh,并且它们将按照您的期望工作。在这个时候,你会看到容器已经在两者之间分布myvm1myvm2

$ docker-machine ssh myvm1 "docker stack ps getstartedlab"

ID            NAME        IMAGE              NODE   DESIRED STATE
jq2g3qp8nzwx  test_web.1  username/repo:tag  myvm1  Running
88wgshobzoxl  test_web.2  username/repo:tag  myvm2  Running
vbb1qbkb0o2z  test_web.3  username/repo:tag  myvm2  Running
ghii74p9budx  test_web.4  username/repo:tag  myvm1  Running
0prmarhavs87  test_web.5  username/repo:tag  myvm2  Running

访问您的群集

你可以从IP地址来访问你的应用程序要么 myvm1myvm2。您创建的网络在它们之间共享,并且负载平衡。运行 docker-machine ls以获取您的虚拟机的IP地址,并在浏览器上访问它们,然后点击刷新(或仅仅curl它们)。您会看到五个可能的容器ID,它们都随机循环,显示了负载平衡。

IP地址工作的原因是群集中的节点参与入口路由网格。这样可以确保在群集中某个端口部署的服务始终将该端口保留给其自身,无论实际运行的是哪个节点。以下是在三节点群集my-web端口8080上发布的服务的路由网格如何显示:

有连通性麻烦?

请记住,为了在群集中使用入口网络,在启用群组模式之前,需要在群集节点之间打开以下端口:

端口7946用于容器网络发现的TCP / UDP。
端口4789 UDP用于容器入口网络。

迭代和缩放您的应用程序

从这里你可以做所有你在docker 服务部分学到的东西。

通过更改docker-compose.yml文件来缩放应用程序。

通过编辑代码来更改应用程序行为。

在这两种情况下,只需docker stack deploy再次运行以部署这些更改。

您可以使用与docker swarm join您使用的相同的命令将任何物理机或虚拟机加入此集群myvm2,并将容量添加到集群中。docker stack deploy稍后运行,您的应用程序将利用新的资源。

清理

你可以移除堆叠docker stack rm。例如:

docker-machine ssh myvm1 "docker stack rm getstartedlab"

保持群体或去除它?

在稍后的某个时候,如果要docker-machine ssh myvm2 “docker swarm leave”在工作人员和docker-machine ssh myvm1 “docker swarm leave –force”管理员上使用,您可以删除此群组

在本部分中,您了解了一个群体,群组中的节点如何可以成为管理者或工作人员,创建了群集,并在其上部署了一个应用程序。你看到Docker的核心命令没有从docker服务部分改变,他们只需要在群集主机上运行。您还看到了Docker网络的强大功能,即使它们在不同的机器上运行,这些功能也可以在容器之间保持负载平衡请求。最后,您学习了如何在集群上迭代和扩展应用程序。

这里有一些您可能希望运行的命令与您的群集进行交互:

docker-machine create --driver virtualbox myvm1 # 创建虚拟机(Mac,Win7,Linux)
docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10
docker-machine env myvm1 # 查看有关您节点的基本信息
docker-machine ssh myvm1 "docker node ls" # 列出你的群组中的节点
docker-machine ssh myvm1 "docker node inspect <node ID>" # 检查节点
docker-machine ssh myvm1 "docker swarm join-token -q worker" # 检查node View连接标记
docker-machine ssh myvm1 # 与VM打开SSH会话; 键入“exit”结束
docker-machine ssh myvm2 "docker swarm leave" # 从集群中移除工人
docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm
docker-machine start myvm1 # 启动当前未运行的虚拟机
docker-machine stop $(docker-machine ls -q) # Stop all running VMs
docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images
docker-machine scp docker-compose.yml myvm1:~ # 将文件复制到节点的主目录
docker-machine ssh myvm1 "docker stack deploy -c <file> <app>" # 部署应用程序

docker Services 服务

了解服务

在分布式应用程序中,应用程序的不同部分称为“服务”。例如,如果您想像一个视频共享站点,它可能包括一个用于在数据库中存储应用程序数据的服务,一个在后台进行视频转码的服务用户上传东西,前端服务等等。

服务只是“生产中的容器”。一个服务只运行一个映像,但它编码映像运行的方式 – 应该使用哪些端口,容器应该运行多少副本,以便服务具有所需的容量,以及所以。扩展服务会更改运行该软件的容器实例的数量,并为该过程中的服务分配更多的计算资源。

幸运的是,使用Docker平台定义,运行和扩展服务非常简单 – 只需编写一个docker-compose.yml文件。

你的第一个docker-compose.yml文件

version: "3"
services:
  web:
    # replace username/repo:tag with your name and image details
    image: username/repository:tag
    deploy:
      replicas: 5
      resources:
        limits:
          cpus: "0.1"
          memory: 50M
      restart_policy:
        condition: on-failure
    ports:
      - "80:80"
    networks:
      - webnet
networks:
  webnet:

docker-compose.yml文件告诉Docker执行以下操作

  • 从注册表中拉出我们在上传的镜像。
  • 运行该映像的五个实例作为调用的服务web,限制每个实例使用,最多使用10%的CPU(跨所有内核)和50MB RAM。
  • 如果发生故障,立即重新启动容器。
  • 将端口80映射到主机web端口80。
  • 指示web容器通过称为负载平衡网络共享端口80 webnet。(在内部,容器本身将web在短暂的端口发布到 80端口。)
  • webnet使用默认设置(这是一个负载平衡的重叠网络)来定义网络。

运行新的负载平衡应用程序

在我们可以使用docker stack deploy命令之前,我们先运行:

docker swarm init

现在我们来运行它 你必须给你的应用程序一个名字。在这里,它设置为 getstartedlab

docker stack deploy -c docker-compose.yml getstartedlab

看到刚刚推出的五个容器的列表:

docker stack ps getstartedlab

您可以curl http://localhost连续运行多次,或者在浏览器中转到该URL,并点击刷新几次。无论哪种方式,您将看到容器ID更改,显示负载平衡; 在每个请求中,以循环方式选择五个副本之一进行响应。

注意:在此阶段,容器可能需要长达30秒才能响应HTTP请求。这并不代表Docker或群组性能,而是一个未满足的Redis依赖关系,我们将在本教程的后面介绍。

缩放应用程序

您可以通过更改replicasdocker-compose.yml,保存更改并重新运行docker stack deploy命令来缩放应用程序:

docker stack deploy -c docker-compose.yml getstartedlab

Docker将进行就地更新,无需首先关闭或者移除容器

现在,重新运行docker stack ps命令以重新配置已部署的实例。例如,如果您放大副本,则会有更多的运行容器。

删除应用程序和群组

将应用程序放在下面docker stack rm

docker stack rm getstartedlab

这会删除应用程序,但是我们的单节点群组仍然运行(如图所示docker node ls)。移除docker swarm leave --force

与Docker一样容易扩展您的应用程序。您在学习如何运行生产中的容器方面迈出了巨大的一步。接下来,您将了解如何在Docker机器集群上运行此应用程序

注意:撰写这样的文件可用于使用Docker定义应用程序,并可以使用Docker Cloud上传到云提供商,也可以使用Docker Enterprise Edition选择的任何硬件或云提供商 。

要简要说明,打字时docker run简单,生产中的容器的真正实现将作为一项服务运行。服务在Compose文件中编写容器的行为,并且此文件可用于扩展,限制和重新部署我们的应用程序。可以使用与启动服务相同的命令运行对应用程序的更改: docker stack deploy

在这个阶段要探索的一些命令:

docker stack ls # 列出该Docker主机上的所有运行的应用程序
docker stack deploy -c <composefile> <appname> # 运行指定的Compose文件
docker stack services <appname> # 列出与应用程序关联的服务
docker stack ps <appname> # 列出与应用程序关联的正在运行的容器
docker stack rm <appname> # 移除一个应用程序

docker Dockerfile创建一个容器,并发布到Docker CLoud

一、定义Dockerfile

创建一个空目录,并在目录中创建dockerfile文件

#创建目录
mkdir /data/docker

#进入目录
cd /data/docker

#创建dockerfile文件
vim Dockerfile

#写入
#使用官方的Python运行时作为父镜像
FROM python:2.7-slim

#设置工作目录
WORKDIR /app

#当前目录的内容复制到容器
ADD . /app

#安装requirements.txt中指定的所需软件包
RUN pip install -r requirements.txt

#对外提供80端口
EXPOSE 80

#设置环境变量
ENV NAME World

#在容器启动时运行app.py
CMD ["python", "app.py"]

#创建 requirements.txt 文件
vim requirements.txt

#写入软件列表
Flask
Redis

#创建app.py文件
vim app.py

#写入
from flask import Flask
from redis import Redis, RedisError
import os
import socket

# Connect to Redis
redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

app = Flask(__name__)

@app.route("/")
def hello():
 try:
 visits = redis.incr("counter")
 except RedisError:
 visits = "<i>cannot connect to Redis, counter disabled</i>"

 html = "<h3>Hello {name}!</h3>" \
 "<b>Hostname:</b> {hostname}<br/>" \
 "<b>Visits:</b> {visits}"
 return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)

if __name__ == "__main__":
 app.run(host='0.0.0.0', port=80)

现在我们看到,pip install -r requirements.txt为Python安装Flask和Redis库,应用程序会打印环境变量NAME以及调用的输出socket.gethostname()。最后,因为Redis没有运行(因为我们只安装了Python库,而不是Redis本身),我们应该期望在这里使用它的尝试将失败并产生错误消息。

二、构建应用程序

这里ls应该显示:

$ ls
Dockerfile		app.py			requirements.txt

现在运行build命令。这将创建一个Docker镜像,我们将使用-t来标记

docker build -t friendlyhello .

你的图像在哪里?它在您机器的本地Docker映像注册表中:

$ docker images

REPOSITORY            TAG                 IMAGE ID
friendlyhello         latest              326387cea398

三、运行应用程序

运行应用程序,将机器的端口4000映射到容器的EXPOSEd端口80,方法-p如下:

docker run -p 4000:80 friendlyhello

您应该看到一个通知,Python正在为您的应用程序提供服务http://0.0.0.0:80。但是该消息来自容器内部,它不知道您将该容器的端口80映射到4000,从而创建正确的URL http://localhost:4000

在网页浏览器中转到该网址,查看在网页上提供的显示内容,包括“Hello World”文本,容器ID和Redis错误消息。

您还可以使用curl shell中的命令来查看相同的内容。

$ curl http://localhost:4000

<h3>Hello World!</h3><b>Hostname:</b> 8fc990912a14<br/><b>Visits:</b> <i>cannot connect to Redis, counter disabled</i>

注意:这个端口重新映射4000:80是为了展示你EXPOSE在内部Dockerfile和你publish使用的 内容之间的区别docker run -p。在后面的步骤中,我们将主机上的端口80映射到容器中的端口80并使用http://localhost

CTRL+C在您的终端中点击退出。

现在让我们在后台运行应用程序,在分离模式下:

docker run -d -p 4000:80 friendlyhello

您的应用程序将获得长容器ID,然后被踢回您的终端。您的容器在后台运行。您还可以看到缩写的容器ID docker ps(并且在运行命令时可以互换):

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED
1fa4ab2cf395        friendlyhello       "python app.py"     28 seconds ago

你会看到CONTAINER ID匹配的是什么http://localhost:4000

现在docker stop用来结束这个过程,用的CONTAINER ID就是这样:

docker stop 1fa4ab2cf395

分享您的图像

为了演示我们刚刚创建的可移植性,让我们上传我们构建的映像,并在其他地方运行它。毕竟,当您要将容器部署到生产中时,您将需要了解如何推送到注册表。

注册表是存储库的集合,存储库是图像集合,类似于GitHub存储库,代码已经被构建。注册表上的帐户可以创建许多存储库。该dockerCLI使用泊坞窗的公共注册表默认情况下。

注意:我们将使用Docker的公共注册表,因为它是免费的和预配置的,但有很多公共选择,您甚至可以使用Docker Trusted Registry设置您自己的私人注册表。

使用您的Docker ID登录

如果您没有Docker帐户,请在cloud.docker.com注册一个。记下您的用户名。

登录到本地计算机上的Docker公共注册表。

docker login

标记图像

将本地映像与注册表上的存储库关联的符号是 username/repository:tag。标签是可选的,但建议,因为它是注册表使Dockport映像版本的机制。给存储库并为上下文标记有意义的名称,例如 get-started:part1。这将把图像放在get-started存储库中并将其标记为part1

现在,把它放在一起来标记图像。运行docker tag image您的用户名,存储库和标签名称,以便映像将上传到您想要的目的地。该命令的语法是:

docker tag image username/repository:tag

例如:

docker tag friendlyhello john/get-started:part1

运行Docker图像以查看您新标记的图像。(你也可以使用docker image ls。)

$ docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
friendlyhello            latest              d9e555c53008        3 minutes ago       195MB
john/get-started         part1               d9e555c53008        3 minutes ago       195MB
python                   2.7-slim            1c7128a655f6        5 days ago          183MB
...

发布图片

将标记的图像上传到存储库:

docker push username/repository:tag

一旦完成,此上传的结果是公开的。如果您登录Docker Hub,则可以使用pull命令查看新图像。

从远程存储库中拉出并运行映像

从现在开始,您可以使用docker run并运行您的应用程序在任何机器上使用此命令:

docker run -p 4000:80 username/repository:tag

如果图像在本机不可用,Docker将从存储库中拉出。

$ docker run -p 4000:80 john/get-started:part1
Unable to find image 'john/get-started:part1' locally
part1: Pulling from orangesnap/get-started
10a267c67f42: Already exists
f68a39a6a5e4: Already exists
9beaffc0cf19: Already exists
3c1fe835fb6b: Already exists
4c9f1fa8fcb8: Already exists
ee7d8f576a14: Already exists
fbccdcced46e: Already exists
Digest: sha256:0601c866aab2adcc6498200efd0f754037e909e5fd42069adeff72d1e2439068
Status: Downloaded newer image for john/get-started:part1
 * Running on http://0.0.0.0:80/ (Press CTRL+C to quit)

注意:如果您没有指定:tag这些命令的部分,:latest则将在构建时和运行映像时假定标记。Docker将使用运行的最后一个版本的图像,而没有指定标签(不一定是最新的图像)。

无论docker run执行什么,它都会将您的图像,以及Python和所有依赖关系从requirements.txt您的代码中提取出来,并运行您的代码。它一起在一个整齐的小包裹,主机不需要安装任何东西,但Docker来运行它。

以下是该页面的基本Docker命令的列表,如果您想在浏览之前先探索一些相关的命令。

docker build -t friendlyname . # 使用此目录的Dockerfile创建映像
docker run -p 4000:80 friendlyname # 运行“友好名称”映射端口4000到80
docker run -d -p 4000:80 friendlyname # 同样的事情,但在分离模式
docker ps # 查看所有正在运行的容器的列表
docker stop <hash> # 正确停止指定的容器
docker ps -a # 查看所有容器的列表,即使是未运行的容器
docker kill <hash> # 强制关闭指定的容器
docker rm <hash> # 从本机中删除指定的容器
docker rm $(docker ps -a -q) # 从本机删除所有容器
docker images -a # 显示本机上的所有镜像
docker rmi <imagename> # 从本机中删除指定的容器
docker rmi $(docker images -q) # 从本机删除所有容器
docker login # 使用Docker凭据登录此CLI会话
docker tag <image> username/repository:tag # Tag <image> 用于上传到注册表
docker push username/repository:tag # 将标记的映像上传到注册表
docker run username/repository:tag # 从注册表运行映像

centos7 下gitlab社区版更换数据库为mysql

第1章 系统准备

[root@test ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[root@test ~]# uname -r
3.10.0-327.el7.x86_64

1.1添加阿里云的镜像

cd /etc/yum.repos.d
#备份原镜像
mv CentOS-Base.repo CentOS-Base.repo.backup
#添加阿里云Base源
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
#添加阿里云epel源
wget https://mirrors.aliyun.com/repo/epel-7.repo
#清除缓存
yum clean all && yum makecache

第2章 yum安装最新版

2.1安装依赖软件

yum install curl policycoreutils openssh-serveropenssh-clients

2.2添加清华大学镜像

vi /etc/yum.repos.d/gitlab-ce.repo
[gitlab-ce]
name=Gitlab CE Repository
baseurl=https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el$releasever/
gpgcheck=0
enabled=1

2.3安装gitlab-ce

yum makecache
yum install gitlab-ce

2.4查看安装gitlab的版本

head -1 /opt/gitlab/version-manifest.txt
gitlab-ce 9.1.2

2.5重新配置并启动Gitlab

# gitlab-ctl reconfigure会把一些过去的config还原,导致修改的端口以及域名等都没有了
gitlab-ctl reconfigure
#重启gitlab-ce
gitlab-ctl restart

第3章 安装mysql5.6.36

3.1添加mysql源

vi /etc/yum.repo.d/mysql.repo
[mysql56-community]
name=MySQL 5.6 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/7/$basearch/
enabled=1
gpgcheck=0

3.2mysql配置

yum -y install mysql-server mysql-devel

#基本配置,新建密码等
mysql_secure_installation

#登录数据库
mysql -uroot -p$password

#查看用户情况
mysql> select user,host from mysql.user;
+------+-----------+
| user | host     |
+------+-----------+
| root | 127.0.0.1 |
| root | ::1      |
| root | localhost |
| root | test     |
+------+-----------+
4 rows in set (0.03 sec)

#创建一个gitlab管理用户
mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.00 sec)

#创建gitlab数据库
mysql> CREATE DATABASE IF NOT EXISTS`gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_general_ci`;
Query OK, 1 row affected (0.00 sec)

#授予git用户对gitlabhq_production数据库所有表的权限
mysql> GRANT SELECT, INSERT, UPDATE, DELETE,CREATE, CREATE TEMPORARY TABLES, DROP, INDEX, ALTER, LOCK TABLES, REFERENCES ON`gitlabhq_production`.* TO 'git'@'localhost';
Query OK, 0 rows affected (0.00 sec)

#使修改用户生效
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> \q
Bye

#测试新用户是否能连接新的数据库
sudo -u git -H mysql -u git -p -Dgitlabhq_production
Enter password:
Reading table information for completion of tableand column names
You can turn off this feature to get a quickerstartup with -A

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 32
Server version: 5.6.36 MySQL Community Server (GPL)

Copyright (c) 2000, 2017, Oracle and/or itsaffiliates. All rights reserved.

Oracle is a registered trademark of OracleCorporation and/or its
affiliates. Other names may be trademarks of theirrespective
owners.

Type 'help;' or '\h' for help. Type '\c' to clearthe current input statement.

mysql>

第4章 配置Gitlab连接mysql

4.1修改/etc/gitlab/gitlab.rb

postgresql['enable'] = false
gitlab_rails['db_adapter'] = 'mysql2'
gitlab_rails['db_encoding'] = 'utf8'
gitlab_rails['db_host'] = '127.0.0.1'
gitlab_rails['db_port'] = '3306'
gitlab_rails['db_username'] = 'git'
gitlab_rails['db_password'] = '123456'
按官方文档重新配置gitlab
gitlab-ctl reconfigure
迁移数据库时出现以下错误

第5章 排错步骤

5.1更换gem源

#查看gem源
/opt/gitlab/embedded/bin/gem source
*** CURRENT SOURCES ***

https://rubygems.org/

#更换开源中国的gem源,否则使用时会出现错误
/opt/gitlab/embedded/bin/gem sources --addhttps://gems.ruby-china.org/ --remove https://rubygems.org/

#查看更好后的gem源
/opt/gitlab/embedded/bin/gem sources
*** CURRENT SOURCES ***

https://gems.ruby-china.org/

#更改配置Gemfile文件的gem源
vi /opt/gitlab/embedded/service/gitlab-rails/ Gemfile
source 'https://gems.ruby-china.org'

5.2bundle install安装更新

#此命令会尝试更新系统中已存在的gem包
/opt/gitlab/embedded/bin/bundle install

#执行该命令需要切换到Gemfile上一级目录才可以运行
cd /opt/gitlab/embedded/service/gitlab-rails/
/opt/gitlab/embedded/bin/bundle install

5.3bundle禁止使用postgresql

vim /opt/gitlab/embedded/service/gitlab-rails/.bundle/config

5.4 安装mysql2 “0.3.20”

gitlab-rake gitlab:check

#安装mysql2 0.3.20版本
/opt/gitlab/embedded/bin/gem install mysql2 -v'0.3.20'

出错

查看文件后发现没有安装gcc软件,导致不能编译文件。
故需要yum安装gcc
yum install gcc –y

/opt/gitlab/embedded/bin/gem install mysql2 -v'0.3.20'
Building native extensions.  This could take a while...
Successfully installed mysql2-0.3.20
Parsing documentation for mysql2-0.3.20
Installing ri documentation for mysql2-0.3.20
Done installing documentation for mysql2 after 1seconds
1 gem installed

5.5重置检查

#重新配置
gitlab-ctl reconfigure
#检查
gitlab-rake gitlab:check

5.6客户端测试

[root@test chen]# touch README.md
[root@test chen]# git add README.md
[root@test chen]# git commit -m "addREADME"
[master(根提交) bed61ad] addREADME
1 filechanged, 0 insertions(+), 0 deletions(-)
create mode100644 README.md
[root@test chen]# git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 216 bytes | 0 bytes/s,done.
Total 3 (delta 0), reused 0 (delta 0)
To git@10.0.0.10:root/chen.git
* [newbranch]      master -> master
分支 master 设置为跟踪来自 origin 的远程分支 master。

成功
参考文档:
https://docs.gitlab.com/ce/install/database_mysql.html
https://docs.gitlab.com/omnibus/settings/database.html#seed-the-database-fresh-installs-only
http://shaonian.blog.51cto.com/2975261/1894664

本文出自 “11659719” 博客