├── mysql ├── slave │ ├── Dockerfile │ └── mysql-slave-local.yaml ├── README.md └── master │ ├── Dockerfile │ ├── database-init.sql │ └── mysql-master-local.yaml ├── .gitignore ├── .image └── pods.png ├── backend-www ├── .dockerignore ├── config │ ├── autoload │ │ ├── dependencies.php │ │ ├── commands.php │ │ ├── annotations.php │ │ ├── services.php │ │ └── server.php │ ├── config.php │ ├── container.php │ └── routes.php ├── app │ ├── Service │ │ ├── UserServiceInterface.php │ │ └── ProductServiceInterface.php │ ├── Contract │ │ └── FakeIdGenerator.php │ └── Controller │ │ └── IndexController.php ├── Dockerfile ├── sbin │ └── hyperf.php ├── composer.json └── backend-www.yaml ├── backend-service ├── .dockerignore ├── config │ ├── autoload │ │ ├── consul.php │ │ ├── commands.php │ │ ├── annotations.php │ │ ├── databases.php │ │ └── server.php │ ├── dependencies.php │ ├── config.php │ └── container.php ├── app │ └── Service │ │ ├── UserServiceInterface.php │ │ └── UserService.php ├── Dockerfile ├── sbin │ └── hyperf.php ├── backend-service.yaml └── composer.json ├── .gitmodules ├── spring-cat ├── src │ └── main │ │ ├── resources │ │ ├── application.properties │ │ └── application.yml │ │ └── java │ │ └── org │ │ └── cat │ │ ├── ProductService.java │ │ ├── boot │ │ └── ApplicationConfig.java │ │ ├── impl │ │ └── ProductServiceImpl.java │ │ └── IndexApplication.java ├── Dockerfile ├── spring-cat.yaml └── pom.xml ├── archlinux-php ├── mirrorlist └── Dockerfile ├── consul ├── consul-test.yaml └── README.md └── README.md /mysql/slave/Dockerfile: -------------------------------------------------------------------------------- 1 | From nacos/nacos-mysql-slave 2 | 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.lock 3 | .DS_Store 4 | runtime 5 | target/ 6 | .idea 7 | -------------------------------------------------------------------------------- /.image/pods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ideal/kubernetes-demo/HEAD/.image/pods.png -------------------------------------------------------------------------------- /backend-www/.dockerignore: -------------------------------------------------------------------------------- 1 | runtime 2 | vendor 3 | composer.lock 4 | backend-www.yaml 5 | -------------------------------------------------------------------------------- /mysql/README.md: -------------------------------------------------------------------------------- 1 | 2 | ## 警告 3 | 4 | 这里的部署只是为了演示,未使用持久化存储,Deployment删除后数据会丢失。 5 | 6 | -------------------------------------------------------------------------------- /backend-service/.dockerignore: -------------------------------------------------------------------------------- 1 | runtime 2 | vendor 3 | composer.lock 4 | backend-service.yaml 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "consul/consul-helm"] 2 | path = consul/consul-helm 3 | url = https://github.com/hashicorp/consul-helm.git 4 | -------------------------------------------------------------------------------- /spring-cat/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | server.port=3000 2 | server.error.whitelabel.enabled=false 3 | logging.level.root=INFO -------------------------------------------------------------------------------- /archlinux-php/mirrorlist: -------------------------------------------------------------------------------- 1 | ## 2 | ## Arch Linux repository mirrorlist 3 | ## 4 | 5 | Server = https://mirrors.ustc.edu.cn/archlinux/$repo/os/$arch 6 | -------------------------------------------------------------------------------- /mysql/master/Dockerfile: -------------------------------------------------------------------------------- 1 | From nacos/nacos-mysql-master 2 | 3 | RUN rm /docker-entrypoint-initdb.d/nacos-init.sql 4 | 5 | COPY database-init.sql /docker-entrypoint-initdb.d 6 | 7 | -------------------------------------------------------------------------------- /backend-www/config/autoload/dependencies.php: -------------------------------------------------------------------------------- 1 | \App\Contract\FakeIdGenerator::class, 7 | ]; 8 | -------------------------------------------------------------------------------- /backend-service/config/autoload/consul.php: -------------------------------------------------------------------------------- 1 | 'http://' . getenv('CONSUL_CONSUL_SERVER_SERVICE_HOST') . ':' 5 | . getenv('CONSUL_CONSUL_SERVER_SERVICE_PORT'), 6 | ]; 7 | -------------------------------------------------------------------------------- /backend-www/app/Service/UserServiceInterface.php: -------------------------------------------------------------------------------- 1 | " 4 | 5 | RUN mkdir /var/www 6 | 7 | ADD target/spring-cat-demo.jar /var/www 8 | 9 | WORKDIR /var/www 10 | 11 | CMD ["java", "-jar", "spring-cat-demo.jar"] 12 | -------------------------------------------------------------------------------- /backend-www/app/Service/ProductServiceInterface.php: -------------------------------------------------------------------------------- 1 | " 4 | 5 | COPY . /var/www 6 | 7 | RUN composer install --no-dev && \ 8 | composer dump-autoload -o && \ 9 | sh vendor/bin/init-proxy.sh 10 | 11 | ENTRYPOINT ["php", "/var/www/sbin/hyperf.php", "start"] 12 | 13 | -------------------------------------------------------------------------------- /backend-www/config/autoload/commands.php: -------------------------------------------------------------------------------- 1 | [ 15 | ], 16 | ]; 17 | -------------------------------------------------------------------------------- /backend-www/app/Contract/FakeIdGenerator.php: -------------------------------------------------------------------------------- 1 | " 4 | 5 | COPY . /var/www 6 | 7 | RUN echo "extension=pdo_mysql" > /etc/php/conf.d/pdo_mysql.ini 8 | 9 | RUN composer install --no-dev && \ 10 | composer dump-autoload -o && \ 11 | sh vendor/bin/init-proxy.sh 12 | 13 | ENTRYPOINT ["php", "/var/www/sbin/hyperf.php", "start"] 14 | 15 | -------------------------------------------------------------------------------- /spring-cat/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | consul: 4 | host: consul-consul-server 5 | port: 8500 6 | discovery: 7 | prefer-ip-address: true 8 | instance-id: ${spring.application.name}-${spring.cloud.client.ip-address} 9 | health-check-path: /health 10 | health-check-interval: 20s 11 | application: 12 | name: ProductService 13 | -------------------------------------------------------------------------------- /consul/consul-test.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: consul-test 5 | spec: 6 | containers: 7 | - name: test 8 | image: "consul:latest" 9 | command: 10 | - "/bin/sh" 11 | - "-ec" 12 | - | 13 | export CONSUL_HTTP_ADDR="${CONSUL_CONSUL_SERVER_SERVICE_HOST}:8500" 14 | printenv 15 | consul kv get aaaa 16 | sleep 300 17 | restartPolicy: Never 18 | -------------------------------------------------------------------------------- /spring-cat/spring-cat.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: spring-cat 5 | labels: 6 | app: spring-cat 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: spring-cat 12 | template: 13 | metadata: 14 | labels: 15 | app: spring-cat 16 | spec: 17 | containers: 18 | - name: spring-cat 19 | image: ideal/spring-cat:latest 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 3000 23 | -------------------------------------------------------------------------------- /mysql/master/database-init.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE `user` ( 2 | `uid` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'uid', 3 | `name` varchar(128) NOT NULL DEFAULT '', 4 | `intro` longtext NOT NULL COMMENT 'intro', 5 | `gmt_create` datetime NOT NULL DEFAULT '2016-12-23 12:00:00' COMMENT '创建时间', 6 | `gmt_modified` datetime NOT NULL DEFAULT '2016-12-23 12:00:00' COMMENT '修改时间', 7 | `user_type` varchar(64) DEFAULT NULL, 8 | PRIMARY KEY (`uid`) 9 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='user'; 10 | 11 | -------------------------------------------------------------------------------- /backend-www/config/autoload/annotations.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'paths' => [ 16 | BASE_PATH . '/app', 17 | ], 18 | 'ignore_annotations' => [ 19 | 'mixin', 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /backend-service/config/autoload/annotations.php: -------------------------------------------------------------------------------- 1 | [ 15 | 'paths' => [ 16 | BASE_PATH . '/app', 17 | ], 18 | 'ignore_annotations' => [ 19 | 'mixin', 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /backend-www/config/config.php: -------------------------------------------------------------------------------- 1 | env('APP_NAME', 'backend-www'), 18 | StdoutLoggerInterface::class => [ 19 | 'log_level' => [ 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /backend-service/config/config.php: -------------------------------------------------------------------------------- 1 | env('APP_NAME', 'backend-service'), 18 | StdoutLoggerInterface::class => [ 19 | 'log_level' => [ 20 | ], 21 | ], 22 | ]; 23 | -------------------------------------------------------------------------------- /spring-cat/src/main/java/org/cat/boot/ApplicationConfig.java: -------------------------------------------------------------------------------- 1 | package org.cat.boot; 2 | 3 | import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImplExporter; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class ApplicationConfig { 9 | 10 | @Bean 11 | public static AutoJsonRpcServiceImplExporter autoJsonRpcServiceImplExporter() { 12 | AutoJsonRpcServiceImplExporter exporter = new AutoJsonRpcServiceImplExporter(); 13 | return exporter; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /backend-www/config/container.php: -------------------------------------------------------------------------------- 1 | get(\Hyperf\Contract\ApplicationInterface::class); 20 | $application->run(); 21 | })(); 22 | -------------------------------------------------------------------------------- /backend-service/sbin/hyperf.php: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env php 2 | get(\Hyperf\Contract\ApplicationInterface::class); 20 | $application->run(); 21 | })(); 22 | -------------------------------------------------------------------------------- /backend-www/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "hyperf/command": "*", 4 | "hyperf/config": "*", 5 | "hyperf/contract": "*", 6 | "hyperf/di": "*", 7 | "hyperf/dispatcher": "*", 8 | "hyperf/event": "*", 9 | "hyperf/exception-handler": "*", 10 | "hyperf/framework": "~1.1.0", 11 | "hyperf/http-server": "*", 12 | "hyperf/utils": "*", 13 | "hyperf/circuit-breaker": "*", 14 | "hyperf/rpc-client": "^1.1", 15 | "hyperf/json-rpc": "^1.1", 16 | "hyperf/rpc-server": "^1.1", 17 | "hyperf/pool": "^1.1", 18 | "hyperf/consul": "^1.1" 19 | }, 20 | "autoload": { 21 | "psr-4": { 22 | "App\\": "app/" 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /spring-cat/src/main/java/org/cat/impl/ProductServiceImpl.java: -------------------------------------------------------------------------------- 1 | package org.cat.impl; 2 | 3 | import com.googlecode.jsonrpc4j.JsonRpcMethod; 4 | import com.googlecode.jsonrpc4j.JsonRpcParam; 5 | import com.googlecode.jsonrpc4j.JsonRpcService; 6 | import com.googlecode.jsonrpc4j.spring.AutoJsonRpcServiceImpl; 7 | import org.cat.ProductService; 8 | import org.springframework.stereotype.Service; 9 | 10 | @Service 11 | @JsonRpcService("/product") 12 | @AutoJsonRpcServiceImpl 13 | public class ProductServiceImpl implements ProductService { 14 | @Override 15 | @JsonRpcMethod("/product/add") 16 | public String add(@JsonRpcParam(value = "name") String name, @JsonRpcParam(value = "price") Double price) 17 | { 18 | return "ok from Java service"; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /backend-www/backend-www.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: backend-www 5 | labels: 6 | app: backend-www 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | app: backend-www 12 | template: 13 | metadata: 14 | labels: 15 | app: backend-www 16 | spec: 17 | containers: 18 | - name: backend-www 19 | image: ideal/backend-www:latest 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 3000 23 | --- 24 | apiVersion: v1 25 | kind: Service 26 | metadata: 27 | name: backend-www 28 | labels: 29 | app: backend-www 30 | spec: 31 | type: LoadBalancer 32 | ports: 33 | - port: 80 34 | targetPort: 3000 35 | selector: 36 | app: backend-www 37 | -------------------------------------------------------------------------------- /backend-service/backend-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: backend-service 5 | labels: 6 | app: backend-service 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | app: backend-service 12 | template: 13 | metadata: 14 | labels: 15 | app: backend-service 16 | spec: 17 | containers: 18 | - name: backend-service 19 | image: ideal/backend-service:latest 20 | imagePullPolicy: Always 21 | ports: 22 | - containerPort: 3010 23 | env: 24 | - name: DB_DATABASE 25 | value: "fatcat_db" 26 | - name: DB_PORT 27 | value: "3306" 28 | - name: DB_USERNAME 29 | value: "fatcat" 30 | - name: DB_PASSWORD 31 | value: "fatcat" 32 | -------------------------------------------------------------------------------- /backend-service/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "require": { 3 | "hyperf/command": "*", 4 | "hyperf/config": "*", 5 | "hyperf/contract": "*", 6 | "hyperf/di": "*", 7 | "hyperf/dispatcher": "*", 8 | "hyperf/event": "*", 9 | "hyperf/exception-handler": "*", 10 | "hyperf/framework": "~1.1.0", 11 | "hyperf/http-server": "*", 12 | "hyperf/utils": "*", 13 | "hyperf/circuit-breaker": "*", 14 | "hyperf/json-rpc": "^1.1", 15 | "hyperf/rpc-server": "^1.1", 16 | "hyperf/pool": "^1.1", 17 | "hyperf/service-governance": "^1.1", 18 | "hyperf/consul": "^1.1", 19 | "hyperf/db-connection": "^1.1" 20 | }, 21 | "autoload": { 22 | "psr-4": { 23 | "App\\": "app/" 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /backend-service/app/Service/UserService.php: -------------------------------------------------------------------------------- 1 | config->get('app_name'); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /spring-cat/src/main/java/org/cat/IndexApplication.java: -------------------------------------------------------------------------------- 1 | package org.cat; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.stereotype.Controller; 6 | import org.springframework.web.bind.annotation.GetMapping; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | 10 | @SpringBootApplication 11 | public class IndexApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(IndexApplication.class, args); 14 | } 15 | 16 | @Controller 17 | public class CatController { 18 | 19 | @RequestMapping("/") 20 | public String root() { 21 | return "forward:/product"; 22 | } 23 | 24 | @GetMapping("/health") 25 | @ResponseBody 26 | public String health() { 27 | return "ok"; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /consul/README.md: -------------------------------------------------------------------------------- 1 | ## 文档 2 | 3 | https://www.consul.io/docs/platform/k8s/run.html 4 | 5 | https://helm.sh/docs/intro/install/ 6 | 7 | ## 步骤 8 | 9 | 1. 10 | 11 | On macOS: 12 | 13 | ```shell 14 | brew install kubernetes-helm 15 | ``` 16 | 17 | On archlinux: 18 | 19 | Add archlinuxcn repo, see https://github.com/archlinuxcn/repo , and then: 20 | 21 | ```shell 22 | sudo pacman -S kubernetes-helm 23 | ``` 24 | 25 | 2. 26 | 27 | ```shell 28 | git clone https://github.com/hashicorp/consul-helm.git 29 | cd consul-helm 30 | git checkout v0.12.0 31 | helm install --name consul ./ 32 | ``` 33 | 34 | 备注: 35 | 36 | 对于阿里云上的Kubernetes集群,修改values.yaml里的storage为20Gi,修改storageClass为alicloud-disk-ssd,然后运行`helm install --name consul ./`。或者也直接不修改values.yaml,直接这样运行`helm install --name consul --set server.storage=20Gi,server.storageClass=alicloud-disk-ssd ./`。因为阿里云针对有些类型的StorageClass存在最小容量限制,参见https://www.alibabacloud.com/help/doc-detail/86612.htm . 37 | 38 | 另外阿里云的Kubernetes网络组件terway,不支持hostPort,需要将templates/server-service.yam l里的clusterIP: None去掉,即使用ClusterIP形式的Service。 39 | -------------------------------------------------------------------------------- /backend-www/config/autoload/services.php: -------------------------------------------------------------------------------- 1 | 'consul', 5 | 'address' => 'http://' . getenv('CONSUL_CONSUL_SERVER_SERVICE_HOST') . ':' 6 | . getenv('CONSUL_CONSUL_SERVER_SERVICE_PORT'), 7 | ]; 8 | 9 | return [ 10 | 'consumers' => [ 11 | [ 12 | 'name' => 'UserService', 13 | 'service' => \App\Service\UserServiceInterface::class, 14 | 'id' => \App\Service\UserServiceInterface::class, 15 | 'protocol' => 'jsonrpc', 16 | 'load_balancer' => 'random', 17 | 'registry' => $registry, 18 | ], 19 | [ 20 | 'name' => 'ProductService', 21 | 'service' => \App\Service\ProductServiceInterface::class, 22 | 'id' => \App\Service\ProductServiceInterface::class, 23 | 'protocol' => 'jsonrpc-http', 24 | 'load_balancer' => 'random', 25 | 'registry' => $registry, 26 | ] 27 | ], 28 | ]; 29 | 30 | -------------------------------------------------------------------------------- /backend-service/config/autoload/databases.php: -------------------------------------------------------------------------------- 1 | [ 5 | 'driver' => env('DB_DRIVER', 'mysql'), 6 | 'write' => [ 7 | 'host' => [ env('MYSQL_MASTER_SERVICE_HOST') ], 8 | ], 9 | 'read' => [ 10 | 'host' => [ env('MYSQL_SLAVE_SERVICE_HOST') ], 11 | ], 12 | 'sticky' => true, 13 | 'database' => env('DB_DATABASE', 'fatcat_db'), 14 | 'port' => env('DB_PORT', 3306), 15 | 'username' => env('DB_USERNAME', 'root'), 16 | 'password' => env('DB_PASSWORD', ''), 17 | 'charset' => env('DB_CHARSET', 'utf8mb4'), 18 | 'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'), 19 | 'prefix' => env('DB_PREFIX', ''), 20 | 'pool' => [ 21 | 'min_connections' => 1, 22 | 'max_connections' => 20, 23 | 'connect_timeout' => 5.0, 24 | 'wait_timeout' => 3.0, 25 | 'heartbeat' => -1, 26 | 'max_idle_time' => (float) env('DB_MAX_IDLE_TIME', 60), 27 | ], 28 | ], 29 | ]; 30 | 31 | -------------------------------------------------------------------------------- /mysql/slave/mysql-slave-local.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql-slave 5 | labels: 6 | app: mysql-slave 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | app: mysql-slave 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql-slave 16 | spec: 17 | containers: 18 | - name: slave 19 | image: ideal/mysql-slave:latest 20 | ports: 21 | - containerPort: 3306 22 | volumeMounts: 23 | - name: mysql-slave-data 24 | mountPath: /var/lib/mysql 25 | env: 26 | - name: MYSQL_ROOT_PASSWORD 27 | value: "root" 28 | - name: MYSQL_REPLICATION_USER 29 | value: 'fatcat_ru' 30 | - name: MYSQL_REPLICATION_PASSWORD 31 | value: 'fatcat_ru' 32 | volumes: 33 | - name: mysql-slave-data 34 | emptyDir: {} 35 | --- 36 | apiVersion: v1 37 | kind: Service 38 | metadata: 39 | name: mysql-slave 40 | labels: 41 | app: mysql-slave 42 | spec: 43 | ports: 44 | - port: 3306 45 | targetPort: 3306 46 | selector: 47 | app: mysql-slave 48 | -------------------------------------------------------------------------------- /mysql/master/mysql-master-local.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: mysql-master 5 | labels: 6 | app: mysql-master 7 | spec: 8 | replicas: 1 9 | selector: 10 | matchLabels: 11 | app: mysql-master 12 | template: 13 | metadata: 14 | labels: 15 | app: mysql-master 16 | spec: 17 | containers: 18 | - name: master 19 | image: ideal/mysql-master:latest 20 | ports: 21 | - containerPort: 3306 22 | volumeMounts: 23 | - name: mysql-master-data 24 | mountPath: /var/lib/mysql 25 | env: 26 | - name: MYSQL_ROOT_PASSWORD 27 | value: "root" 28 | - name: MYSQL_DATABASE 29 | value: "fatcat_db" 30 | - name: MYSQL_USER 31 | value: "fatcat" 32 | - name: MYSQL_PASSWORD 33 | value: "fatcat" 34 | - name: MYSQL_REPLICATION_USER 35 | value: 'fatcat_ru' 36 | - name: MYSQL_REPLICATION_PASSWORD 37 | value: 'fatcat_ru' 38 | volumes: 39 | - name: mysql-master-data 40 | emptyDir: {} 41 | --- 42 | apiVersion: v1 43 | kind: Service 44 | metadata: 45 | name: mysql-master 46 | labels: 47 | app: mysql-master 48 | spec: 49 | ports: 50 | - port: 3306 51 | targetPort: 3306 52 | selector: 53 | app: mysql-master 54 | -------------------------------------------------------------------------------- /archlinux-php/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM archlinux 2 | 3 | LABEL maintainer="ideal " 4 | 5 | ARG timezone 6 | 7 | ENV TIMEZONE=${timezone:-"Asia/Shanghai"} 8 | 9 | RUN ln -sf /usr/share/zoneinfo/${TIMEZONE} /etc/localtime 10 | 11 | COPY mirrorlist /etc/pacman.d/mirrorlist 12 | 13 | RUN echo -e '[archlinuxcn]\n\ 14 | Server = https://repo.archlinuxcn.org/$arch\n\ 15 | ' >> /etc/pacman.conf 16 | 17 | RUN pacman -Syy --noconfirm && \ 18 | pacman -S --noconfirm awk && \ 19 | pacman-key --init && \ 20 | pacman-key -r F9F9FA97A403F63E && \ 21 | pacman-key -f F9F9FA97A403F63E && \ 22 | pacman-key --lsign-key F9F9FA97A403F63E && \ 23 | pacman -Su --noconfirm && \ 24 | pacman -S --noconfirm gettext grep wget unzip php php-embed php-swoole php-redis composer && \ 25 | pacman -Scc --noconfirm && \ 26 | rm -rf /etc/pacman.d/gnupg/{openpgp-revocs.d/,private-keys-v1.d/,pubring.gpg~}* && \ 27 | rm -rf /var/cache/pacman/pkg/* /tmp/* && \ 28 | { \ 29 | echo "upload_max_filesize=100M"; \ 30 | echo "post_max_size=105M"; \ 31 | echo "memory_limit=1024M"; \ 32 | echo "date.timezone=${TIMEZONE}"; \ 33 | } | tee /etc/php/conf.d/overrides.ini && \ 34 | { \ 35 | echo "extension=swoole.so"; \ 36 | echo 'swoole.use_shortname="Off"'; \ 37 | } | tee /etc/php/conf.d/swoole.ini && \ 38 | php -v && \ 39 | php -m 40 | 41 | RUN composer config -g repo.packagist composer https://mirrors.aliyun.com/composer/ 42 | 43 | WORKDIR /var/www 44 | 45 | -------------------------------------------------------------------------------- /backend-www/config/autoload/server.php: -------------------------------------------------------------------------------- 1 | SWOOLE_BASE, 18 | 'servers' => [ 19 | [ 20 | 'name' => 'http', 21 | 'type' => Server::SERVER_HTTP, 22 | 'host' => '0.0.0.0', 23 | 'port' => 3000, 24 | 'sock_type' => SWOOLE_SOCK_TCP, 25 | 'callbacks' => [ 26 | SwooleEvent::ON_REQUEST => [Hyperf\HttpServer\Server::class, 'onRequest'], 27 | ], 28 | ], 29 | ], 30 | 'settings' => [ 31 | 'enable_coroutine' => true, 32 | 'worker_num' => swoole_cpu_num() * 2, 33 | 'pid_file' => BASE_PATH . '/runtime/hyperf.pid', 34 | 'open_tcp_nodelay' => true, 35 | 'max_coroutine' => 100000, 36 | 'open_http2_protocol' => true, 37 | 'max_request' => 100000, 38 | 'socket_buffer_size' => 2 * 1024 * 1024, 39 | ], 40 | 'callbacks' => [ 41 | SwooleEvent::ON_BEFORE_START => [Hyperf\Framework\Bootstrap\ServerStartCallback::class, 'beforeStart'], 42 | SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], 43 | SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], 44 | ], 45 | ]; 46 | -------------------------------------------------------------------------------- /backend-www/app/Controller/IndexController.php: -------------------------------------------------------------------------------- 1 | withHeader("Content-Type", "text/html; charset=utf-8"); 40 | return $response->raw("hello 😊"); 41 | } 42 | 43 | public function get(int $id) 44 | { 45 | return (string) $id; 46 | } 47 | 48 | /** 49 | * @CircuitBreaker(timeout=0.5, failCounter=1, successCounter=1) 50 | * 51 | */ 52 | public function create(RequestInterface $request) 53 | { 54 | $name = $request->input('name'); 55 | if (!$name) { 56 | return 'Need a name'; 57 | } 58 | 59 | return $this->userService->create($name); 60 | } 61 | 62 | public function product() 63 | { 64 | return $this->productService->add("iPhone", 20.05); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /backend-service/config/autoload/server.php: -------------------------------------------------------------------------------- 1 | SWOOLE_BASE, 18 | 'servers' => [ 19 | [ 20 | 'name' => 'jsonrpc', 21 | 'type' => Server::SERVER_BASE, 22 | 'host' => '0.0.0.0', 23 | 'port' => 3010, 24 | 'sock_type' => SWOOLE_SOCK_TCP, 25 | 'callbacks' => [ 26 | SwooleEvent::ON_RECEIVE => [\Hyperf\JsonRpc\TcpServer::class, 'onReceive'], 27 | ], 28 | 'settings' => [ 29 | 'open_eof_split' => true, 30 | 'package_eof' => "\r\n", 31 | ], 32 | ], 33 | ], 34 | 'settings' => [ 35 | 'enable_coroutine' => true, 36 | 'worker_num' => swoole_cpu_num() * 2, 37 | 'pid_file' => BASE_PATH . '/runtime/hyperf.pid', 38 | 'open_tcp_nodelay' => true, 39 | 'max_coroutine' => 100000, 40 | 'open_http2_protocol' => true, 41 | 'max_request' => 100000, 42 | 'socket_buffer_size' => 2 * 1024 * 1024, 43 | ], 44 | 'callbacks' => [ 45 | SwooleEvent::ON_BEFORE_START => [Hyperf\Framework\Bootstrap\ServerStartCallback::class, 'beforeStart'], 46 | SwooleEvent::ON_WORKER_START => [Hyperf\Framework\Bootstrap\WorkerStartCallback::class, 'onWorkerStart'], 47 | SwooleEvent::ON_PIPE_MESSAGE => [Hyperf\Framework\Bootstrap\PipeMessageCallback::class, 'onPipeMessage'], 48 | ], 49 | ]; 50 | -------------------------------------------------------------------------------- /spring-cat/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.boot 8 | spring-boot-starter-parent 9 | 2.2.0.RELEASE 10 | 11 | 12 | org.cat.spring-cat 13 | demo 14 | 1.1.0-SNAPSHOT 15 | spring-cat-demo 16 | Demo project for Spring Boot 17 | 18 | 19 | 1.8 20 | 21 | 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-web 26 | 27 | 28 | org.springframework.cloud 29 | spring-cloud-starter-consul-discovery 30 | 2.2.0.RELEASE 31 | 32 | 33 | com.github.briandilley.jsonrpc4j 34 | jsonrpc4j 35 | 1.5.3 36 | 37 | 38 | javax.servlet 39 | javax.servlet-api 40 | 3.1.0 41 | provided 42 | 43 | 44 | 45 | 46 | spring-cat-demo 47 | 48 | 49 | org.springframework.boot 50 | spring-boot-maven-plugin 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Kubernetes-demo 2 | 3 | demo for running services in Kubernetes. 4 | 5 | # Steps 6 | 7 | 0. install `kubectl` and `helm`, run `helm init` to init both server (install tiller) and client. 8 | 9 | 1. Optional: build and push Docker images (if you need) under `mysql/master`, `mysql/slave`, `archlinux-php`, `backend-service`, `backend-www`. If you build and push images yourself, you need to change container image in the corresponding yaml files. 10 | 11 | 2. Deploy MySQL master: 12 | 13 | ```shell 14 | kubectl apply -f mysql/master/mysql-master-local.yaml 15 | ``` 16 | 17 | 3. Deploy MySQL slave: 18 | 19 | ```shell 20 | kubectl apply -f mysql/slave/mysql-slave-local.yaml 21 | ``` 22 | 23 | 4. Deploy consul: 24 | 25 | Change server.storage and server.storageClass to fit your requirement. 26 | 27 | ```shell 28 | git submodule update --init 29 | cd consul/consul-helm && helm install --name consul --set server.storage=20Gi,server.storageClass=alicloud-disk-ssd ./ 30 | ``` 31 | 32 | 5. Deploy backend-service, which provides jsonrpc service for backend-www: 33 | 34 | ```shell 35 | kubectl apply -f backend-service/backend-service.yaml 36 | ``` 37 | 38 | 6. Deploy backend-www, which calls backend-service and provides HTTP web access: 39 | 40 | ```shell 41 | kubectl apply -f backend-www/backend-www.yaml 42 | ``` 43 | 44 | 7. Test if all are ok: 45 | 46 | ```shell 47 | # get backend-www's EXTERNAL-IP 48 | kubectl get svc 49 | 50 | # If you have EXTERNAL-IP 51 | curl -i -XPOST "EXTERNAL-IP/user?name=fatcat" 52 | 53 | # If you have no EXTERNAL-IP 54 | # Change xxxx to your Pod name 55 | kubectl exec backend-www-xxxx -- curl -i -XPOST "backend-www/user?name=fatcat" 56 | 57 | # Check fatcat_db.user table in mysql master or slave if data inserted 58 | ... 59 | ``` 60 | 61 | 8. Maybe the most exciting features of Kubernetes: 62 | 63 | ```shell 64 | # scaling 65 | kubectl scale --replicas 6 deployment/backend-service 66 | kubectl scale --replicas 6 deployment/backend-www 67 | kubectl scale --replicas 4 deployment/mysql-slave 68 | 69 | # autoscaler 70 | kubectl autoscale deployment/backend-service --min=2 --max=20 --cpu-percent=50 71 | 72 | # graceful upgrading 73 | kubectl set image deployment/backend-service backend-service=ideal/backend-service:0.0.1 74 | 75 | # graceful restarting 76 | kubectl rollout restart deployment/backend-www 77 | ``` 78 | 79 | ![Pods](.image/pods.png?raw=true "Pods") 80 | 81 | --------------------------------------------------------------------------------